mirror of
https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
synced 2025-11-30 12:01:02 +08:00
发布: 14_编写SPI_OLED模块驱动程序,15_编写OLED驱动_上机实验_IMX6ULL,15_编写OLED驱动_上机实验_STM32MP157
This commit is contained in:
270
IMX6ULL/doc_pic/11_SPI/14_编写SPI_OLED模块驱动程序.md
Normal file
270
IMX6ULL/doc_pic/11_SPI/14_编写SPI_OLED模块驱动程序.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 编写SPI_OLED模块驱动程序 #
|
||||
|
||||
* 源码:
|
||||
|
||||

|
||||
|
||||
## 1. 硬件
|
||||
|
||||
### 1.1 原理图
|
||||
|
||||
IMX6ULL:
|
||||
|
||||

|
||||
|
||||
STM32MP157:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
原理图:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 1.2 连接
|
||||
|
||||
无论是使用IMX6ULL开发板还是STM32MP157开发板,都有类似的扩展板。把OLED模块接到扩展板的SPI_A插座上,如下:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 2. 编写设备树
|
||||
|
||||
### 2.1.1 IMX6ULL
|
||||
|
||||

|
||||
|
||||
DC引脚使用GPIO4_20,也需在设备树里指定。
|
||||
|
||||
设备树如下:
|
||||
|
||||
```shell
|
||||
&ecspi1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_ecspi1>;
|
||||
|
||||
fsl,spi-num-chipselects = <2>;
|
||||
cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>, <&gpio4 24 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
oled: oled {
|
||||
compatible = "100ask,oled";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
dc-gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 2.1.2 STM32MP157
|
||||
|
||||

|
||||
|
||||
DC引脚使用GPIOA_13,也需要在设备树里指定。
|
||||
|
||||
设备树如下:
|
||||
|
||||
```shell
|
||||
&spi5 {
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&spi5_pins_a>;
|
||||
pinctrl-1 = <&spi5_sleep_pins_a>;
|
||||
status = "okay";
|
||||
cs-gpios = <&gpioh 5 GPIO_ACTIVE_LOW>, <&gpioz 4 GPIO_ACTIVE_LOW>;
|
||||
spidev: icm20608@0{
|
||||
compatible = "invensense,icm20608";
|
||||
interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-parent = <&gpioz>;
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
oled: oled@1{
|
||||
compatible = "100ask,oled";
|
||||
spi-max-frequency = <10000000>;
|
||||
reg = <1>;
|
||||
dc-gpios = <&gpioa 13 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&oled_pins>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
arch/arm/boot/dts/stm32mp157-100ask-pinctrl.dtsi:
|
||||
|
||||
```shell
|
||||
oled_pins: oled_pins {
|
||||
pins {
|
||||
pinmux = <STM32_PINMUX('A', 13, GPIO)>;
|
||||
bias-disable;
|
||||
drive-push-pull;
|
||||
slew-rate = <1>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 3. 编译替换设备树
|
||||
|
||||
### 3.1 IMX6ULL
|
||||
|
||||
#### 3.1.1 设置工具链
|
||||
|
||||
```shell
|
||||
export ARCH=arm
|
||||
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
|
||||
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
|
||||
```
|
||||
|
||||
|
||||
#### 3.1.2 编译、替换设备树
|
||||
|
||||
* 编译设备树:
|
||||
在Ubuntu的IMX6ULL内核目录下执行如下命令,
|
||||
得到设备树文件:`arch/arm/boot/dts/100ask_imx6ull-14x14.dtb`
|
||||
|
||||
```shell
|
||||
make dtbs
|
||||
```
|
||||
|
||||
* 复制到NFS目录:
|
||||
|
||||
```shell
|
||||
$ cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs/
|
||||
```
|
||||
|
||||
* 开发板上挂载NFS文件系统
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
|
||||
```
|
||||
|
||||
* 更新设备树
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# cp /mnt/100ask_imx6ull-14x14.dtb /boot
|
||||
[root@100ask:~]# sync
|
||||
```
|
||||
|
||||
* 重启开发板
|
||||
|
||||
|
||||
|
||||
### 3.2 STM32MP157
|
||||
|
||||
#### 3.2.1 设置工具链
|
||||
|
||||
```shell
|
||||
export ARCH=arm
|
||||
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
|
||||
export PATH=$PATH:/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
|
||||
```
|
||||
|
||||
|
||||
#### 3.2.2 编译、替换设备树
|
||||
|
||||
* 编译设备树:
|
||||
在Ubuntu的STM32MP157内核目录下执行如下命令,
|
||||
得到设备树文件:`arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dtb`
|
||||
|
||||
```shell
|
||||
make dtbs
|
||||
```
|
||||
|
||||
* 复制到NFS目录:
|
||||
|
||||
```shell
|
||||
$ cp arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dtb ~/nfs_rootfs/
|
||||
```
|
||||
|
||||
* 开发板上挂载NFS文件系统
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
|
||||
```
|
||||
|
||||
* 确定设备树分区挂载在哪里
|
||||
|
||||
由于版本变化,STM32MP157单板上烧录的系统可能有细微差别。
|
||||
在开发板上执行`cat /proc/mounts`后,可以得到两种结果(见下图):
|
||||
|
||||
* mmcblk2p2分区挂载在/boot目录下(下图左边):无需特殊操作,下面把文件复制到/boot目录即可
|
||||
|
||||
* mmcblk2p2挂载在/mnt目录下(下图右边)
|
||||
|
||||
* 在视频里、后面文档里,都是更新/boot目录下的文件,所以要先执行以下命令重新挂载:
|
||||
* `mount /dev/mmcblk2p2 /boot`
|
||||
|
||||

|
||||
|
||||
* 更新设备树
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# cp /mnt/stm32mp157c-100ask-512d-lcd-v1.dtb /boot/
|
||||
[root@100ask:~]# sync
|
||||
```
|
||||
|
||||
* 重启开发板
|
||||
|
||||
|
||||
|
||||
## 4. 编译OLED驱动
|
||||
|
||||
|
||||
|
||||
## 5. 编译APP
|
||||
|
||||
```shell
|
||||
arm-buildroot-linux-gnueabihf-gcc -o spi_oled spi_oled.c
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 6. 上机实验
|
||||
|
||||
如果spidev没有被编译进内核,那么先执行:
|
||||
|
||||
```shell
|
||||
insmod oled_drv.ko
|
||||
```
|
||||
|
||||
|
||||
|
||||
确定设备节点:
|
||||
|
||||
```shell
|
||||
ls /dev/100ask_oled
|
||||
```
|
||||
|
||||
|
||||
|
||||
假设设备节点为`/dev/100ask_oled`,执行测试程序:
|
||||
|
||||
```shell
|
||||
./spi_oled /dev/100ask_oled
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
270
IMX6ULL/doc_pic/11_SPI/15_编写OLED驱动_上机实验.md
Normal file
270
IMX6ULL/doc_pic/11_SPI/15_编写OLED驱动_上机实验.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 编写OLED驱动_上机实验 #
|
||||
|
||||
* 源码:
|
||||
|
||||

|
||||
|
||||
## 1. 硬件
|
||||
|
||||
### 1.1 原理图
|
||||
|
||||
IMX6ULL:
|
||||
|
||||

|
||||
|
||||
STM32MP157:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
原理图:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 1.2 连接
|
||||
|
||||
无论是使用IMX6ULL开发板还是STM32MP157开发板,都有类似的扩展板。把OLED模块接到扩展板的SPI_A插座上,如下:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 2. 编写设备树
|
||||
|
||||
### 2.1.1 IMX6ULL
|
||||
|
||||

|
||||
|
||||
DC引脚使用GPIO4_20,也需在设备树里指定。
|
||||
|
||||
设备树如下:arch/arm/boot/dts/100ask_imx6ull-14x14.dts
|
||||
|
||||
```shell
|
||||
&ecspi1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_ecspi1>;
|
||||
|
||||
fsl,spi-num-chipselects = <2>;
|
||||
cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>, <&gpio4 24 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
oled: oled {
|
||||
compatible = "100ask,oled";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
dc-gpios = <&gpio4 20 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 2.1.2 STM32MP157
|
||||
|
||||

|
||||
|
||||
DC引脚使用GPIOA_13,也需要在设备树里指定。
|
||||
|
||||
设备树如下:`arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dts`
|
||||
|
||||
```shell
|
||||
&spi5 {
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&spi5_pins_a>;
|
||||
pinctrl-1 = <&spi5_sleep_pins_a>;
|
||||
status = "okay";
|
||||
cs-gpios = <&gpioh 5 GPIO_ACTIVE_LOW>, <&gpioz 4 GPIO_ACTIVE_LOW>;
|
||||
spidev: icm20608@0{
|
||||
compatible = "invensense,icm20608";
|
||||
interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-parent = <&gpioz>;
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
oled: oled@1{
|
||||
compatible = "100ask,oled";
|
||||
spi-max-frequency = <10000000>;
|
||||
reg = <1>;
|
||||
dc-gpios = <&gpioa 13 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&oled_pins>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
arch/arm/boot/dts/stm32mp157-100ask-pinctrl.dtsi:
|
||||
|
||||
```shell
|
||||
oled_pins: oled_pins {
|
||||
pins {
|
||||
pinmux = <STM32_PINMUX('A', 13, GPIO)>;
|
||||
bias-disable;
|
||||
drive-push-pull;
|
||||
slew-rate = <1>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 3. 编译替换设备树
|
||||
|
||||
### 3.1 IMX6ULL
|
||||
|
||||
#### 3.1.1 设置工具链
|
||||
|
||||
```shell
|
||||
export ARCH=arm
|
||||
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
|
||||
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
|
||||
```
|
||||
|
||||
|
||||
#### 3.1.2 编译、替换设备树
|
||||
|
||||
* 编译设备树:
|
||||
在Ubuntu的IMX6ULL内核目录下执行如下命令,
|
||||
得到设备树文件:`arch/arm/boot/dts/100ask_imx6ull-14x14.dtb`
|
||||
|
||||
```shell
|
||||
make dtbs
|
||||
```
|
||||
|
||||
* 复制到NFS目录:
|
||||
|
||||
```shell
|
||||
$ cp arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs/
|
||||
```
|
||||
|
||||
* 开发板上挂载NFS文件系统
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
|
||||
```
|
||||
|
||||
* 更新设备树
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# cp /mnt/100ask_imx6ull-14x14.dtb /boot
|
||||
[root@100ask:~]# sync
|
||||
```
|
||||
|
||||
* 重启开发板
|
||||
|
||||
|
||||
|
||||
### 3.2 STM32MP157
|
||||
|
||||
#### 3.2.1 设置工具链
|
||||
|
||||
```shell
|
||||
export ARCH=arm
|
||||
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
|
||||
export PATH=$PATH:/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
|
||||
```
|
||||
|
||||
|
||||
#### 3.2.2 编译、替换设备树
|
||||
|
||||
* 编译设备树:
|
||||
在Ubuntu的STM32MP157内核目录下执行如下命令,
|
||||
得到设备树文件:`arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dtb`
|
||||
|
||||
```shell
|
||||
make dtbs
|
||||
```
|
||||
|
||||
* 复制到NFS目录:
|
||||
|
||||
```shell
|
||||
$ cp arch/arm/boot/dts/stm32mp157c-100ask-512d-lcd-v1.dtb ~/nfs_rootfs/
|
||||
```
|
||||
|
||||
* 开发板上挂载NFS文件系统
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.1.137:/home/book/nfs_rootfs /mnt
|
||||
```
|
||||
|
||||
* 确定设备树分区挂载在哪里
|
||||
|
||||
由于版本变化,STM32MP157单板上烧录的系统可能有细微差别。
|
||||
在开发板上执行`cat /proc/mounts`后,可以得到两种结果(见下图):
|
||||
|
||||
* mmcblk2p2分区挂载在/boot目录下(下图左边):无需特殊操作,下面把文件复制到/boot目录即可
|
||||
|
||||
* mmcblk2p2挂载在/mnt目录下(下图右边)
|
||||
|
||||
* 在视频里、后面文档里,都是更新/boot目录下的文件,所以要先执行以下命令重新挂载:
|
||||
* `mount /dev/mmcblk2p2 /boot`
|
||||
|
||||

|
||||
|
||||
* 更新设备树
|
||||
|
||||
```shell
|
||||
[root@100ask:~]# cp /mnt/stm32mp157c-100ask-512d-lcd-v1.dtb /boot/
|
||||
[root@100ask:~]# sync
|
||||
```
|
||||
|
||||
* 重启开发板
|
||||
|
||||
|
||||
|
||||
## 4. 编译OLED驱动
|
||||
|
||||
|
||||
|
||||
## 5. 编译APP
|
||||
|
||||
```shell
|
||||
arm-buildroot-linux-gnueabihf-gcc -o spi_oled spi_oled.c
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 6. 上机实验
|
||||
|
||||
如果spidev没有被编译进内核,那么先执行:
|
||||
|
||||
```shell
|
||||
insmod oled_drv.ko
|
||||
```
|
||||
|
||||
|
||||
|
||||
确定设备节点:
|
||||
|
||||
```shell
|
||||
ls /dev/100ask_oled
|
||||
```
|
||||
|
||||
|
||||
|
||||
假设设备节点为`/dev/100ask_oled`,执行测试程序:
|
||||
|
||||
```shell
|
||||
./spi_oled /dev/100ask_oled
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
IMX6ULL/doc_pic/11_SPI/15_编写OLED驱动_上机实验.tif
Normal file
BIN
IMX6ULL/doc_pic/11_SPI/15_编写OLED驱动_上机实验.tif
Normal file
Binary file not shown.
BIN
IMX6ULL/doc_pic/11_SPI/pic/74_src_oled_drv.png
Normal file
BIN
IMX6ULL/doc_pic/11_SPI/pic/74_src_oled_drv.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
IMX6ULL/doc_pic/11_SPI/pic/75_src_oled_drv_ok.png
Normal file
BIN
IMX6ULL/doc_pic/11_SPI/pic/75_src_oled_drv_ok.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@@ -13,10 +13,6 @@
|
||||
|
||||
#include "font.h"
|
||||
|
||||
//为0 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
static int fd_spidev;
|
||||
static int dc_pin_num;
|
||||
|
||||
|
||||
22
IMX6ULL/source/11_SPI/07_oled_use_mydrv/Makefile
Normal file
22
IMX6ULL/source/11_SPI/07_oled_use_mydrv/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
|
||||
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
|
||||
# 2.1 ARCH, 比如: export ARCH=arm64
|
||||
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
|
||||
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
|
||||
# 请参考各开发板的高级用户使用手册
|
||||
|
||||
KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88
|
||||
|
||||
all:
|
||||
make -C $(KERN_DIR) M=`pwd` modules
|
||||
$(CROSS_COMPILE)gcc -o spi_oled spi_oled.c
|
||||
|
||||
clean:
|
||||
make -C $(KERN_DIR) M=`pwd` modules clean
|
||||
rm -rf modules.order spi_oled
|
||||
|
||||
obj-m += oled_drv.o
|
||||
|
||||
|
||||
106
IMX6ULL/source/11_SPI/07_oled_use_mydrv/font.h
Normal file
106
IMX6ULL/source/11_SPI/07_oled_use_mydrv/font.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _FONT_H_
|
||||
#define _FONT_H_
|
||||
const unsigned char oled_asc2_8x16[95][16]=
|
||||
{
|
||||
{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},//016
|
||||
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//117
|
||||
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},//218
|
||||
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},//319
|
||||
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},//420
|
||||
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},//521
|
||||
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},//622
|
||||
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},//723
|
||||
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},//824
|
||||
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},//925
|
||||
{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},//A33
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},//B34
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},//C35
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},//D36
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},//E37
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},//F38
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},//G39
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},//H40
|
||||
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//I41
|
||||
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},//J42
|
||||
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},//K43
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},//L44
|
||||
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},//M45
|
||||
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},//N46
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},//O47
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},//P48
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},//Q49
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},//R50
|
||||
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},//S51
|
||||
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//T52
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//U53
|
||||
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},//V54
|
||||
{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},//W55
|
||||
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},//X56
|
||||
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//Y57
|
||||
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},//Z58
|
||||
{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},//a65
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},//b66
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},//c67
|
||||
{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},//d68
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},//e69
|
||||
{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//f70
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},//g71
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//h72
|
||||
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//i73
|
||||
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},//j74
|
||||
{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},//k75
|
||||
{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//l76
|
||||
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},//m77
|
||||
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//n78
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//o79
|
||||
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},//p80
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},//q81
|
||||
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},//r82
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},//s83
|
||||
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},//t84
|
||||
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},//u85
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},//v86
|
||||
{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},//w87
|
||||
{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},//x88
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},//y89
|
||||
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},//z90
|
||||
{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
|
||||
};
|
||||
const unsigned char hz_1616[][32]={
|
||||
{0x02,0x00,0x02,0x00,0xE2,0xFF,0x22,0x42,0x22,0x42,0x32,0x42,0x2A,0x42,0x26,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0xE2,0xFF,0x02,0x00,0x02,0x00,0x00,0x00},/*"百",0*/
|
||||
{0x00,0x00,0xF8,0xFF,0x01,0x00,0x02,0x00,0x00,0x00,0xE2,0x1F,0x22,0x08,0x22,0x08,0x22,0x08,0xE2,0x1F,0x02,0x00,0x02,0x40,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"问",1*/
|
||||
{0x00,0x00,0xFE,0xFF,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x0E,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x4E,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"网",2*/
|
||||
};
|
||||
#endif
|
||||
300
IMX6ULL/source/11_SPI/07_oled_use_mydrv/oled_drv.c
Normal file
300
IMX6ULL/source/11_SPI/07_oled_use_mydrv/oled_drv.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Simple synchronous userspace interface to SPI devices
|
||||
*
|
||||
* Copyright (C) 2006 SWAPP
|
||||
* Andrea Paterniani <a.paterniani@swapp-eng.it>
|
||||
* Copyright (C) 2007 David Brownell (simplification, cleanup)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct spi_device *oled;
|
||||
static int major;
|
||||
static gpio_desc *dc_gpio;
|
||||
|
||||
static void dc_pin_init(void)
|
||||
{
|
||||
gpiod_direction_output(dc_gpio, 1);
|
||||
}
|
||||
|
||||
static void oled_set_dc_pin(int val)
|
||||
{
|
||||
gpiod_set_value(dc_gpio, val);
|
||||
}
|
||||
|
||||
static void spi_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
spi_write(oled, buf, len);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: oled_write_cmd
|
||||
* 功能描述: oled向特定地址写入数据或者命令
|
||||
* 输入参数:@uc_data :要写入的数据
|
||||
@uc_cmd:为1则表示写入数据,为0表示写入命令
|
||||
* 输出参数:无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/04 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd)
|
||||
{
|
||||
unsigned char uc_read=0;
|
||||
if(uc_cmd==0)
|
||||
{
|
||||
oled_set_dc_pin(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
oled_set_dc_pin(1);//拉高,表示写入数据
|
||||
}
|
||||
spi_write_datas(&uc_data, 1);//写入
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: oled_init
|
||||
* 功能描述: oled_init的初始化,包括SPI控制器得初始化
|
||||
* 输入参数:无
|
||||
* 输出参数: 初始化的结果
|
||||
* 返 回 值: 成功则返回0,否则返回-1
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static int oled_init(void)
|
||||
{
|
||||
unsigned char uc_dev_id = 0;
|
||||
|
||||
oled_write_cmd_data(0xae,OLED_CMD);//关闭显示
|
||||
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//设置 lower column address
|
||||
oled_write_cmd_data(0x10,OLED_CMD);//设置 higher column address
|
||||
|
||||
oled_write_cmd_data(0x40,OLED_CMD);//设置 display start line
|
||||
|
||||
oled_write_cmd_data(0xB0,OLED_CMD);//设置page address
|
||||
|
||||
oled_write_cmd_data(0x81,OLED_CMD);// contract control
|
||||
oled_write_cmd_data(0x66,OLED_CMD);//128
|
||||
|
||||
oled_write_cmd_data(0xa1,OLED_CMD);//设置 segment remap
|
||||
|
||||
oled_write_cmd_data(0xa6,OLED_CMD);//normal /reverse
|
||||
|
||||
oled_write_cmd_data(0xa8,OLED_CMD);//multiple ratio
|
||||
oled_write_cmd_data(0x3f,OLED_CMD);//duty = 1/64
|
||||
|
||||
oled_write_cmd_data(0xc8,OLED_CMD);//com scan direction
|
||||
|
||||
oled_write_cmd_data(0xd3,OLED_CMD);//set displat offset
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd5,OLED_CMD);//set osc division
|
||||
oled_write_cmd_data(0x80,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd9,OLED_CMD);//ser pre-charge period
|
||||
oled_write_cmd_data(0x1f,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xda,OLED_CMD);//set com pins
|
||||
oled_write_cmd_data(0x12,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xdb,OLED_CMD);//set vcomh
|
||||
oled_write_cmd_data(0x30,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0x8d,OLED_CMD);//set charge pump disable
|
||||
oled_write_cmd_data(0x14,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xaf,OLED_CMD);//set dispkay on
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{ oled_write_cmd_data(0xb0+y,OLED_CMD);
|
||||
oled_write_cmd_data((x&0x0f),OLED_CMD);
|
||||
oled_write_cmd_data(((x&0xf0)>>4)|0x10,OLED_CMD);
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
/* 根据cmd操作硬件 */
|
||||
switch (cmd)
|
||||
{
|
||||
case OLED_IOC_INIT: /* init */
|
||||
{
|
||||
dc_pin_init();
|
||||
oled_init();
|
||||
break;
|
||||
}
|
||||
|
||||
case OLED_IOC_SET_POS: /* set pos */
|
||||
{
|
||||
x = arg & 0xff;
|
||||
y = (arg >> 8) & 0xff;
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spidev_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *f_pos)
|
||||
{
|
||||
char *ker_buf;
|
||||
int err;
|
||||
|
||||
ker_buf = kmalloc(count, GFP_KERNEL);
|
||||
err = copy_from_user(ker_buf, buf, count);
|
||||
|
||||
oled_set_dc_pin(1);//拉高,表示写入数据
|
||||
spi_write_datas(ker_buf, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations spidev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
/* REVISIT switch to aio primitives, so that userspace
|
||||
* gets more complete API coverage. It'll simplify things
|
||||
* too, except for the locking.
|
||||
*/
|
||||
.write = spidev_write,
|
||||
.unlocked_ioctl = spidev_ioctl,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* The main reason to have this class is to make mdev/udev create the
|
||||
* /dev/spidevB.C character device nodes exposing our userspace API.
|
||||
* It also simplifies memory management.
|
||||
*/
|
||||
|
||||
static struct class *spidev_class;
|
||||
|
||||
static const struct of_device_id spidev_dt_ids[] = {
|
||||
{ .compatible = "100ask,oled" },
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int spidev_probe(struct spi_device *spi)
|
||||
{
|
||||
/* 1. 记录spi_device */
|
||||
oled = spi;
|
||||
|
||||
/* 2. 注册字符设备 */
|
||||
major = register_chrdev(0, "100ask_oled", &spidev_fops);
|
||||
spidev_class = class_create(THIS_MODULE, "100ask_oled");
|
||||
device_create(spidev_class, NULL, MKDEV(major, 0), NULL, "100ask_oled");
|
||||
|
||||
/* 3. 获得GPIO引脚 */
|
||||
dc_gpio = gpiod_get(&spi->dev, "dc", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spidev_remove(struct spi_device *spi)
|
||||
{
|
||||
gpiod_put(dc_gpio);
|
||||
|
||||
/* 反注册字符设备 */
|
||||
device_destroy(spidev_class, MKDEV(major, 0));
|
||||
class_destroy(spidev_class);
|
||||
unregister_chrdev(major, "100ask_oled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver spidev_spi_driver = {
|
||||
.driver = {
|
||||
.name = "100ask_spi_oled_drv",
|
||||
.of_match_table = of_match_ptr(spidev_dt_ids),
|
||||
},
|
||||
.probe = spidev_probe,
|
||||
.remove = spidev_remove,
|
||||
|
||||
/* NOTE: suspend/resume methods are not necessary here.
|
||||
* We don't do anything except pass the requests to/from
|
||||
* the underlying controller. The refrigerator handles
|
||||
* most issues; the controller driver handles the rest.
|
||||
*/
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init spidev_init(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = spi_register_driver(&spidev_spi_driver);
|
||||
if (status < 0) {
|
||||
}
|
||||
return status;
|
||||
}
|
||||
module_init(spidev_init);
|
||||
|
||||
static void __exit spidev_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&spidev_spi_driver);
|
||||
}
|
||||
module_exit(spidev_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
239
IMX6ULL/source/11_SPI/07_oled_use_mydrv/spi_oled.c
Normal file
239
IMX6ULL/source/11_SPI/07_oled_use_mydrv/spi_oled.c
Normal file
@@ -0,0 +1,239 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
|
||||
//为0 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
static int fd_spidev;
|
||||
static int dc_pin_num;
|
||||
|
||||
|
||||
void oled_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
write(fd_spidev, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Clear
|
||||
* 功能描述: 整个屏幕显示数据清0
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Clear(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_All
|
||||
* 功能描述: 整个屏幕显示全部点亮,可以用于检查坏点
|
||||
* 输入参数:无
|
||||
* 输出参数:无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_All(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0xff, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{
|
||||
ioctl(fd_spidev, OLED_IOC_SET_POS, x | (y << 8));
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Char
|
||||
* 功能描述:在某个位置显示字符 1-9
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@c :要显示的字符的ascii码
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c)
|
||||
{
|
||||
int i = 0;
|
||||
/* 得到字模 */
|
||||
const unsigned char *dots = oled_asc2_8x16[c - ' '];
|
||||
|
||||
/* 发给OLED */
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
// oled_write_cmd_data(dots[i], OLED_DATA);
|
||||
oled_write_datas(&dots[0], 8);
|
||||
|
||||
OLED_DIsp_Set_Pos(x, y+1);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
//oled_write_cmd_data(dots[i+8], OLED_DATA);
|
||||
oled_write_datas(&dots[8], 8);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_String
|
||||
* 功能描述: 在指定位置显示字符串
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@str :要显示的字符串
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_String(int x, int y, char *str)
|
||||
{
|
||||
unsigned char j=0;
|
||||
while (str[j])
|
||||
{
|
||||
OLED_DIsp_Char(x, y, str[j]);//显示单个字符
|
||||
x += 8;
|
||||
if(x > 127)
|
||||
{
|
||||
x = 0;
|
||||
y += 2;
|
||||
}//移动显示位置
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_CHinese
|
||||
* 功能描述:在指定位置显示汉字
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@chr :要显示的汉字,三个汉字“百问网”中选择一个
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no)
|
||||
{
|
||||
unsigned char t,adder=0;
|
||||
OLED_DIsp_Set_Pos(x,y);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示上半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2], 1);
|
||||
adder+=1;
|
||||
}
|
||||
OLED_DIsp_Set_Pos(x,y+1);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示下半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2+1], 1);
|
||||
adder+=1;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Test
|
||||
* 功能描述: 整个屏幕显示测试
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Test(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OLED_DIsp_String(0, 0, "wiki.100ask.net");
|
||||
OLED_DIsp_String(0, 2, "book.100ask.net");
|
||||
OLED_DIsp_String(0, 4, "bbs.100ask.net");
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{ //显示汉字 百问网
|
||||
OLED_DIsp_CHinese(32+i*16, 6, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* spi_oled /dev/100ask_oled */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: %s /dev/100ask_oled\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd_spidev = open(argv[1], O_RDWR);
|
||||
if (fd_spidev < 0) {
|
||||
printf("open %s err\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ioctl(fd_spidev, OLED_IOC_INIT);
|
||||
|
||||
OLED_DIsp_Clear();
|
||||
|
||||
OLED_DIsp_Test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
IMX6ULL/source/11_SPI/07_oled_use_mydrv/spi_oled.h
Normal file
17
IMX6ULL/source/11_SPI/07_oled_use_mydrv/spi_oled.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _OLED_H_
|
||||
#define _OLED_H_
|
||||
|
||||
void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd);
|
||||
int oled_init(void);
|
||||
int oled_fill_data(unsigned char fill_Data);
|
||||
void OLED_DIsp_Clear(void);
|
||||
void OLED_DIsp_All(void);
|
||||
void OLED_DIsp_Set_Pos(int x, int y);
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c);
|
||||
void OLED_DIsp_String(int x, int y, char *str);
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no);
|
||||
void OLED_DIsp_Test();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
22
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/Makefile
Normal file
22
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
|
||||
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
|
||||
# 2.1 ARCH, 比如: export ARCH=arm64
|
||||
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
|
||||
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
|
||||
# 请参考各开发板的高级用户使用手册
|
||||
|
||||
KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88
|
||||
|
||||
all:
|
||||
make -C $(KERN_DIR) M=`pwd` modules
|
||||
$(CROSS_COMPILE)gcc -o spi_oled spi_oled.c
|
||||
|
||||
clean:
|
||||
make -C $(KERN_DIR) M=`pwd` modules clean
|
||||
rm -rf modules.order spi_oled
|
||||
|
||||
obj-m += oled_drv.o
|
||||
|
||||
|
||||
106
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/font.h
Normal file
106
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/font.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _FONT_H_
|
||||
#define _FONT_H_
|
||||
const unsigned char oled_asc2_8x16[95][16]=
|
||||
{
|
||||
{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},//016
|
||||
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//117
|
||||
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},//218
|
||||
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},//319
|
||||
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},//420
|
||||
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},//521
|
||||
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},//622
|
||||
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},//723
|
||||
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},//824
|
||||
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},//925
|
||||
{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},//A33
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},//B34
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},//C35
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},//D36
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},//E37
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},//F38
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},//G39
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},//H40
|
||||
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//I41
|
||||
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},//J42
|
||||
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},//K43
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},//L44
|
||||
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},//M45
|
||||
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},//N46
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},//O47
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},//P48
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},//Q49
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},//R50
|
||||
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},//S51
|
||||
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//T52
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//U53
|
||||
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},//V54
|
||||
{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},//W55
|
||||
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},//X56
|
||||
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//Y57
|
||||
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},//Z58
|
||||
{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},//a65
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},//b66
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},//c67
|
||||
{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},//d68
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},//e69
|
||||
{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//f70
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},//g71
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//h72
|
||||
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//i73
|
||||
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},//j74
|
||||
{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},//k75
|
||||
{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//l76
|
||||
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},//m77
|
||||
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//n78
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//o79
|
||||
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},//p80
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},//q81
|
||||
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},//r82
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},//s83
|
||||
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},//t84
|
||||
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},//u85
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},//v86
|
||||
{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},//w87
|
||||
{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},//x88
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},//y89
|
||||
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},//z90
|
||||
{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
|
||||
};
|
||||
const unsigned char hz_1616[][32]={
|
||||
{0x02,0x00,0x02,0x00,0xE2,0xFF,0x22,0x42,0x22,0x42,0x32,0x42,0x2A,0x42,0x26,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0xE2,0xFF,0x02,0x00,0x02,0x00,0x00,0x00},/*"百",0*/
|
||||
{0x00,0x00,0xF8,0xFF,0x01,0x00,0x02,0x00,0x00,0x00,0xE2,0x1F,0x22,0x08,0x22,0x08,0x22,0x08,0xE2,0x1F,0x02,0x00,0x02,0x40,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"问",1*/
|
||||
{0x00,0x00,0xFE,0xFF,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x0E,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x4E,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"网",2*/
|
||||
};
|
||||
#endif
|
||||
299
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/oled_drv.c
Normal file
299
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/oled_drv.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Simple synchronous userspace interface to SPI devices
|
||||
*
|
||||
* Copyright (C) 2006 SWAPP
|
||||
* Andrea Paterniani <a.paterniani@swapp-eng.it>
|
||||
* Copyright (C) 2007 David Brownell (simplification, cleanup)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
//<2F><>? 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct spi_device *oled;
|
||||
static int major;
|
||||
static struct gpio_desc *dc_gpio;
|
||||
|
||||
static void dc_pin_init(void)
|
||||
{
|
||||
gpiod_direction_output(dc_gpio, 1);
|
||||
}
|
||||
|
||||
static void oled_set_dc_pin(int val)
|
||||
{
|
||||
gpiod_set_value(dc_gpio, val);
|
||||
}
|
||||
|
||||
static void spi_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
spi_write(oled, buf, len);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称<E5908D><E7A7B0>?oled_write_cmd
|
||||
* 功能描述<E68F8F><E8BFB0>?oled向特定地址写入数据或者命<E88085><E591BD>? * 输入参数:@uc_data :要写入的数据
|
||||
@uc_cmd:<3A><>?则表示写入数据,<E68DAE><EFBC8C>?表示写入命令
|
||||
* 输出参数:无
|
||||
* <20><>?<3F><>?值: <20><>? * 修改日期 版本<E78988><E69CAC>? 修改<E4BFAE><E694B9>? 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/04 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd)
|
||||
{
|
||||
if(uc_cmd==0)
|
||||
{
|
||||
oled_set_dc_pin(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
oled_set_dc_pin(1);//拉高,表示写入数<E585A5><E695B0>? }
|
||||
spi_write_datas(&uc_data, 1);//写入
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称<E5908D><E7A7B0>?oled_init
|
||||
* 功能描述<E68F8F><E8BFB0>?oled_init的初始化,包括SPI控制器得初始<E5889D><E5A78B>? * 输入参数:无
|
||||
* 输出参数<E58F82><E695B0>?初始化的结果
|
||||
* <20><>?<3F><>?值: 成功则返<E58899><E8BF94>?,否则返<E58899><E8BF94>?1
|
||||
* 修改日期 版本<E78988><E69CAC>? 修改<E4BFAE><E694B9>? 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static int oled_init(void)
|
||||
{
|
||||
oled_write_cmd_data(0xae,OLED_CMD);//关闭显示
|
||||
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//设置 lower column address
|
||||
oled_write_cmd_data(0x10,OLED_CMD);//设置 higher column address
|
||||
|
||||
oled_write_cmd_data(0x40,OLED_CMD);//设置 display start line
|
||||
|
||||
oled_write_cmd_data(0xB0,OLED_CMD);//设置page address
|
||||
|
||||
oled_write_cmd_data(0x81,OLED_CMD);// contract control
|
||||
oled_write_cmd_data(0x66,OLED_CMD);//128
|
||||
|
||||
oled_write_cmd_data(0xa1,OLED_CMD);//设置 segment remap
|
||||
|
||||
oled_write_cmd_data(0xa6,OLED_CMD);//normal /reverse
|
||||
|
||||
oled_write_cmd_data(0xa8,OLED_CMD);//multiple ratio
|
||||
oled_write_cmd_data(0x3f,OLED_CMD);//duty = 1/64
|
||||
|
||||
oled_write_cmd_data(0xc8,OLED_CMD);//com scan direction
|
||||
|
||||
oled_write_cmd_data(0xd3,OLED_CMD);//set displat offset
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd5,OLED_CMD);//set osc division
|
||||
oled_write_cmd_data(0x80,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd9,OLED_CMD);//ser pre-charge period
|
||||
oled_write_cmd_data(0x1f,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xda,OLED_CMD);//set com pins
|
||||
oled_write_cmd_data(0x12,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xdb,OLED_CMD);//set vcomh
|
||||
oled_write_cmd_data(0x30,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0x8d,OLED_CMD);//set charge pump disable
|
||||
oled_write_cmd_data(0x14,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xaf,OLED_CMD);//set dispkay on
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称<E5908D><E7A7B0>?OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位<E79A84><E4BD8D>? * 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数<E58F82><E695B0>?<3F><>? * <20><>?<3F><>?值:
|
||||
* 修改日期 版本<E78988><E69CAC>? 修改<E4BFAE><E694B9>? 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{ oled_write_cmd_data(0xb0+y,OLED_CMD);
|
||||
oled_write_cmd_data((x&0x0f),OLED_CMD);
|
||||
oled_write_cmd_data(((x&0xf0)>>4)|0x10,OLED_CMD);
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
/* 根据cmd操作硬件 */
|
||||
switch (cmd)
|
||||
{
|
||||
case OLED_IOC_INIT: /* init */
|
||||
{
|
||||
dc_pin_init();
|
||||
oled_init();
|
||||
break;
|
||||
}
|
||||
|
||||
case OLED_IOC_SET_POS: /* set pos */
|
||||
{
|
||||
x = arg & 0xff;
|
||||
y = (arg >> 8) & 0xff;
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spidev_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *f_pos)
|
||||
{
|
||||
char *ker_buf;
|
||||
int err;
|
||||
|
||||
ker_buf = kmalloc(count, GFP_KERNEL);
|
||||
err = copy_from_user(ker_buf, buf, count);
|
||||
|
||||
oled_set_dc_pin(1);//拉高,表示写入数<E585A5><E695B0>? spi_write_datas(ker_buf, count);
|
||||
kfree(ker_buf);
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations spidev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
/* REVISIT switch to aio primitives, so that userspace
|
||||
* gets more complete API coverage. It'll simplify things
|
||||
* too, except for the locking.
|
||||
*/
|
||||
.write = spidev_write,
|
||||
.unlocked_ioctl = spidev_ioctl,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* The main reason to have this class is to make mdev/udev create the
|
||||
* /dev/spidevB.C character device nodes exposing our userspace API.
|
||||
* It also simplifies memory management.
|
||||
*/
|
||||
|
||||
static struct class *spidev_class;
|
||||
|
||||
static const struct of_device_id spidev_dt_ids[] = {
|
||||
{ .compatible = "100ask,oled" },
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int spidev_probe(struct spi_device *spi)
|
||||
{
|
||||
/* 1. 记录spi_device */
|
||||
oled = spi;
|
||||
|
||||
/* 2. 注册字符设备 */
|
||||
major = register_chrdev(0, "100ask_oled", &spidev_fops);
|
||||
spidev_class = class_create(THIS_MODULE, "100ask_oled");
|
||||
device_create(spidev_class, NULL, MKDEV(major, 0), NULL, "100ask_oled");
|
||||
|
||||
/* 3. 获得GPIO引脚 */
|
||||
dc_gpio = gpiod_get(&spi->dev, "dc", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spidev_remove(struct spi_device *spi)
|
||||
{
|
||||
gpiod_put(dc_gpio);
|
||||
|
||||
/* 反注册字符设<E7ACA6><E8AEBE>?*/
|
||||
device_destroy(spidev_class, MKDEV(major, 0));
|
||||
class_destroy(spidev_class);
|
||||
unregister_chrdev(major, "100ask_oled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver spidev_spi_driver = {
|
||||
.driver = {
|
||||
.name = "100ask_spi_oled_drv",
|
||||
.of_match_table = of_match_ptr(spidev_dt_ids),
|
||||
},
|
||||
.probe = spidev_probe,
|
||||
.remove = spidev_remove,
|
||||
|
||||
/* NOTE: suspend/resume methods are not necessary here.
|
||||
* We don't do anything except pass the requests to/from
|
||||
* the underlying controller. The refrigerator handles
|
||||
* most issues; the controller driver handles the rest.
|
||||
*/
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init spidev_init(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = spi_register_driver(&spidev_spi_driver);
|
||||
if (status < 0) {
|
||||
}
|
||||
return status;
|
||||
}
|
||||
module_init(spidev_init);
|
||||
|
||||
static void __exit spidev_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&spidev_spi_driver);
|
||||
}
|
||||
module_exit(spidev_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
241
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/spi_oled.c
Normal file
241
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/spi_oled.c
Normal file
@@ -0,0 +1,241 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
|
||||
//为0 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
static int fd_spidev;
|
||||
static int dc_pin_num;
|
||||
|
||||
|
||||
void OLED_DIsp_Set_Pos(int x, int y);
|
||||
|
||||
void oled_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
write(fd_spidev, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Clear
|
||||
* 功能描述: 整个屏幕显示数据清0
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Clear(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_All
|
||||
* 功能描述: 整个屏幕显示全部点亮,可以用于检查坏点
|
||||
* 输入参数:无
|
||||
* 输出参数:无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_All(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0xff, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{
|
||||
ioctl(fd_spidev, OLED_IOC_SET_POS, x | (y << 8));
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Char
|
||||
* 功能描述:在某个位置显示字符 1-9
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@c :要显示的字符的ascii码
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c)
|
||||
{
|
||||
int i = 0;
|
||||
/* 得到字模 */
|
||||
const unsigned char *dots = oled_asc2_8x16[c - ' '];
|
||||
|
||||
/* 发给OLED */
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
// oled_write_cmd_data(dots[i], OLED_DATA);
|
||||
oled_write_datas(&dots[0], 8);
|
||||
|
||||
OLED_DIsp_Set_Pos(x, y+1);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
//oled_write_cmd_data(dots[i+8], OLED_DATA);
|
||||
oled_write_datas(&dots[8], 8);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_String
|
||||
* 功能描述: 在指定位置显示字符串
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@str :要显示的字符串
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_String(int x, int y, char *str)
|
||||
{
|
||||
unsigned char j=0;
|
||||
while (str[j])
|
||||
{
|
||||
OLED_DIsp_Char(x, y, str[j]);//显示单个字符
|
||||
x += 8;
|
||||
if(x > 127)
|
||||
{
|
||||
x = 0;
|
||||
y += 2;
|
||||
}//移动显示位置
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_CHinese
|
||||
* 功能描述:在指定位置显示汉字
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@chr :要显示的汉字,三个汉字“百问网”中选择一个
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no)
|
||||
{
|
||||
unsigned char t,adder=0;
|
||||
OLED_DIsp_Set_Pos(x,y);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示上半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2], 1);
|
||||
adder+=1;
|
||||
}
|
||||
OLED_DIsp_Set_Pos(x,y+1);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示下半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2+1], 1);
|
||||
adder+=1;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Test
|
||||
* 功能描述: 整个屏幕显示测试
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Test(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OLED_DIsp_String(0, 0, "wiki.100ask.net");
|
||||
OLED_DIsp_String(0, 2, "book.100ask.net");
|
||||
OLED_DIsp_String(0, 4, "bbs.100ask.net");
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{ //显示汉字 百问网
|
||||
OLED_DIsp_CHinese(32+i*16, 6, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* spi_oled /dev/100ask_oled */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: %s /dev/100ask_oled\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd_spidev = open(argv[1], O_RDWR);
|
||||
if (fd_spidev < 0) {
|
||||
printf("open %s err\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ioctl(fd_spidev, OLED_IOC_INIT);
|
||||
|
||||
OLED_DIsp_Clear();
|
||||
|
||||
OLED_DIsp_Test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/spi_oled.h
Normal file
17
IMX6ULL/source/11_SPI/08_oled_use_mydrv_ok/spi_oled.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _OLED_H_
|
||||
#define _OLED_H_
|
||||
|
||||
void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd);
|
||||
int oled_init(void);
|
||||
int oled_fill_data(unsigned char fill_Data);
|
||||
void OLED_DIsp_Clear(void);
|
||||
void OLED_DIsp_All(void);
|
||||
void OLED_DIsp_Set_Pos(int x, int y);
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c);
|
||||
void OLED_DIsp_String(int x, int y, char *str);
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no);
|
||||
void OLED_DIsp_Test();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -558,6 +558,14 @@ git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
|
||||
13_编写DAC驱动_上机实验_STM32MP157
|
||||
```
|
||||
|
||||
* 2021.04.29 发布"SPI子系统":
|
||||
|
||||
```shell
|
||||
14_编写SPI_OLED模块驱动程序
|
||||
15_编写OLED驱动_上机实验_IMX6ULL
|
||||
15_编写OLED驱动_上机实验_STM32MP157
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
21
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/Makefile
Normal file
21
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
# 1. 使用不同的开发板内核<E58685><E6A0B8>? 一定要修改KERN_DIR
|
||||
# 2. KERN_DIR中的内核要事先配置、编<E38081><E7BC96>? 为了能编译内<E8AF91><E58685>? 要先设置下列环境变量:
|
||||
# 2.1 ARCH, 比如: export ARCH=arm64
|
||||
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
|
||||
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相<E5AE9A><E79BB8>?
|
||||
# 请参考各开发板的高级用户使用手<E794A8><E6898B>?
|
||||
KERN_DIR = /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4
|
||||
|
||||
all:
|
||||
make -C $(KERN_DIR) M=`pwd` modules
|
||||
$(CROSS_COMPILE)gcc -o spi_oled spi_oled.c
|
||||
|
||||
clean:
|
||||
make -C $(KERN_DIR) M=`pwd` modules clean
|
||||
rm -rf modules.order spi_oled
|
||||
|
||||
obj-m += oled_drv.o
|
||||
|
||||
|
||||
106
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/font.h
Normal file
106
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/font.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _FONT_H_
|
||||
#define _FONT_H_
|
||||
const unsigned char oled_asc2_8x16[95][16]=
|
||||
{
|
||||
{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},//016
|
||||
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//117
|
||||
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},//218
|
||||
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},//319
|
||||
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},//420
|
||||
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},//521
|
||||
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},//622
|
||||
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},//723
|
||||
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},//824
|
||||
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},//925
|
||||
{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},//A33
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},//B34
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},//C35
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},//D36
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},//E37
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},//F38
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},//G39
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},//H40
|
||||
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//I41
|
||||
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},//J42
|
||||
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},//K43
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},//L44
|
||||
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},//M45
|
||||
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},//N46
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},//O47
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},//P48
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},//Q49
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},//R50
|
||||
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},//S51
|
||||
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//T52
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//U53
|
||||
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},//V54
|
||||
{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},//W55
|
||||
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},//X56
|
||||
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//Y57
|
||||
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},//Z58
|
||||
{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},//a65
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},//b66
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},//c67
|
||||
{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},//d68
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},//e69
|
||||
{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//f70
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},//g71
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//h72
|
||||
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//i73
|
||||
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},//j74
|
||||
{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},//k75
|
||||
{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//l76
|
||||
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},//m77
|
||||
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//n78
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//o79
|
||||
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},//p80
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},//q81
|
||||
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},//r82
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},//s83
|
||||
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},//t84
|
||||
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},//u85
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},//v86
|
||||
{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},//w87
|
||||
{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},//x88
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},//y89
|
||||
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},//z90
|
||||
{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
|
||||
};
|
||||
const unsigned char hz_1616[][32]={
|
||||
{0x02,0x00,0x02,0x00,0xE2,0xFF,0x22,0x42,0x22,0x42,0x32,0x42,0x2A,0x42,0x26,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0xE2,0xFF,0x02,0x00,0x02,0x00,0x00,0x00},/*"百",0*/
|
||||
{0x00,0x00,0xF8,0xFF,0x01,0x00,0x02,0x00,0x00,0x00,0xE2,0x1F,0x22,0x08,0x22,0x08,0x22,0x08,0xE2,0x1F,0x02,0x00,0x02,0x40,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"问",1*/
|
||||
{0x00,0x00,0xFE,0xFF,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x0E,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x4E,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"网",2*/
|
||||
};
|
||||
#endif
|
||||
300
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/oled_drv.c
Normal file
300
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/oled_drv.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Simple synchronous userspace interface to SPI devices
|
||||
*
|
||||
* Copyright (C) 2006 SWAPP
|
||||
* Andrea Paterniani <a.paterniani@swapp-eng.it>
|
||||
* Copyright (C) 2007 David Brownell (simplification, cleanup)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct spi_device *oled;
|
||||
static int major;
|
||||
static gpio_desc *dc_gpio;
|
||||
|
||||
static void dc_pin_init(void)
|
||||
{
|
||||
gpiod_direction_output(dc_gpio, 1);
|
||||
}
|
||||
|
||||
static void oled_set_dc_pin(int val)
|
||||
{
|
||||
gpiod_set_value(dc_gpio, val);
|
||||
}
|
||||
|
||||
static void spi_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
spi_write(oled, buf, len);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: oled_write_cmd
|
||||
* 功能描述: oled向特定地址写入数据或者命令
|
||||
* 输入参数:@uc_data :要写入的数据
|
||||
@uc_cmd:为1则表示写入数据,为0表示写入命令
|
||||
* 输出参数:无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/04 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd)
|
||||
{
|
||||
unsigned char uc_read=0;
|
||||
if(uc_cmd==0)
|
||||
{
|
||||
oled_set_dc_pin(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
oled_set_dc_pin(1);//拉高,表示写入数据
|
||||
}
|
||||
spi_write_datas(&uc_data, 1);//写入
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: oled_init
|
||||
* 功能描述: oled_init的初始化,包括SPI控制器得初始化
|
||||
* 输入参数:无
|
||||
* 输出参数: 初始化的结果
|
||||
* 返 回 值: 成功则返回0,否则返回-1
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static int oled_init(void)
|
||||
{
|
||||
unsigned char uc_dev_id = 0;
|
||||
|
||||
oled_write_cmd_data(0xae,OLED_CMD);//关闭显示
|
||||
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//设置 lower column address
|
||||
oled_write_cmd_data(0x10,OLED_CMD);//设置 higher column address
|
||||
|
||||
oled_write_cmd_data(0x40,OLED_CMD);//设置 display start line
|
||||
|
||||
oled_write_cmd_data(0xB0,OLED_CMD);//设置page address
|
||||
|
||||
oled_write_cmd_data(0x81,OLED_CMD);// contract control
|
||||
oled_write_cmd_data(0x66,OLED_CMD);//128
|
||||
|
||||
oled_write_cmd_data(0xa1,OLED_CMD);//设置 segment remap
|
||||
|
||||
oled_write_cmd_data(0xa6,OLED_CMD);//normal /reverse
|
||||
|
||||
oled_write_cmd_data(0xa8,OLED_CMD);//multiple ratio
|
||||
oled_write_cmd_data(0x3f,OLED_CMD);//duty = 1/64
|
||||
|
||||
oled_write_cmd_data(0xc8,OLED_CMD);//com scan direction
|
||||
|
||||
oled_write_cmd_data(0xd3,OLED_CMD);//set displat offset
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd5,OLED_CMD);//set osc division
|
||||
oled_write_cmd_data(0x80,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd9,OLED_CMD);//ser pre-charge period
|
||||
oled_write_cmd_data(0x1f,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xda,OLED_CMD);//set com pins
|
||||
oled_write_cmd_data(0x12,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xdb,OLED_CMD);//set vcomh
|
||||
oled_write_cmd_data(0x30,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0x8d,OLED_CMD);//set charge pump disable
|
||||
oled_write_cmd_data(0x14,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xaf,OLED_CMD);//set dispkay on
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{ oled_write_cmd_data(0xb0+y,OLED_CMD);
|
||||
oled_write_cmd_data((x&0x0f),OLED_CMD);
|
||||
oled_write_cmd_data(((x&0xf0)>>4)|0x10,OLED_CMD);
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
/* 根据cmd操作硬件 */
|
||||
switch (cmd)
|
||||
{
|
||||
case OLED_IOC_INIT: /* init */
|
||||
{
|
||||
dc_pin_init();
|
||||
oled_init();
|
||||
break;
|
||||
}
|
||||
|
||||
case OLED_IOC_SET_POS: /* set pos */
|
||||
{
|
||||
x = arg & 0xff;
|
||||
y = (arg >> 8) & 0xff;
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spidev_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *f_pos)
|
||||
{
|
||||
char *ker_buf;
|
||||
int err;
|
||||
|
||||
ker_buf = kmalloc(count, GFP_KERNEL);
|
||||
err = copy_from_user(ker_buf, buf, count);
|
||||
|
||||
oled_set_dc_pin(1);//拉高,表示写入数据
|
||||
spi_write_datas(ker_buf, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations spidev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
/* REVISIT switch to aio primitives, so that userspace
|
||||
* gets more complete API coverage. It'll simplify things
|
||||
* too, except for the locking.
|
||||
*/
|
||||
.write = spidev_write,
|
||||
.unlocked_ioctl = spidev_ioctl,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* The main reason to have this class is to make mdev/udev create the
|
||||
* /dev/spidevB.C character device nodes exposing our userspace API.
|
||||
* It also simplifies memory management.
|
||||
*/
|
||||
|
||||
static struct class *spidev_class;
|
||||
|
||||
static const struct of_device_id spidev_dt_ids[] = {
|
||||
{ .compatible = "100ask,oled" },
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int spidev_probe(struct spi_device *spi)
|
||||
{
|
||||
/* 1. 记录spi_device */
|
||||
oled = spi;
|
||||
|
||||
/* 2. 注册字符设备 */
|
||||
major = register_chrdev(0, "100ask_oled", &spidev_fops);
|
||||
spidev_class = class_create(THIS_MODULE, "100ask_oled");
|
||||
device_create(spidev_class, NULL, MKDEV(major, 0), NULL, "100ask_oled");
|
||||
|
||||
/* 3. 获得GPIO引脚 */
|
||||
dc_gpio = gpiod_get(&spi->dev, "dc", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spidev_remove(struct spi_device *spi)
|
||||
{
|
||||
gpiod_put(dc_gpio);
|
||||
|
||||
/* 反注册字符设备 */
|
||||
device_destroy(spidev_class, MKDEV(major, 0));
|
||||
class_destroy(spidev_class);
|
||||
unregister_chrdev(major, "100ask_oled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver spidev_spi_driver = {
|
||||
.driver = {
|
||||
.name = "100ask_spi_oled_drv",
|
||||
.of_match_table = of_match_ptr(spidev_dt_ids),
|
||||
},
|
||||
.probe = spidev_probe,
|
||||
.remove = spidev_remove,
|
||||
|
||||
/* NOTE: suspend/resume methods are not necessary here.
|
||||
* We don't do anything except pass the requests to/from
|
||||
* the underlying controller. The refrigerator handles
|
||||
* most issues; the controller driver handles the rest.
|
||||
*/
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init spidev_init(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = spi_register_driver(&spidev_spi_driver);
|
||||
if (status < 0) {
|
||||
}
|
||||
return status;
|
||||
}
|
||||
module_init(spidev_init);
|
||||
|
||||
static void __exit spidev_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&spidev_spi_driver);
|
||||
}
|
||||
module_exit(spidev_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
239
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/spi_oled.c
Normal file
239
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/spi_oled.c
Normal file
@@ -0,0 +1,239 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
|
||||
//为0 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
static int fd_spidev;
|
||||
static int dc_pin_num;
|
||||
|
||||
|
||||
void oled_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
write(fd_spidev, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Clear
|
||||
* 功能描述: 整个屏幕显示数据清0
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Clear(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_All
|
||||
* 功能描述: 整个屏幕显示全部点亮,可以用于检查坏点
|
||||
* 输入参数:无
|
||||
* 输出参数:无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_All(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0xff, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{
|
||||
ioctl(fd_spidev, OLED_IOC_SET_POS, x | (y << 8));
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Char
|
||||
* 功能描述:在某个位置显示字符 1-9
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@c :要显示的字符的ascii码
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c)
|
||||
{
|
||||
int i = 0;
|
||||
/* 得到字模 */
|
||||
const unsigned char *dots = oled_asc2_8x16[c - ' '];
|
||||
|
||||
/* 发给OLED */
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
// oled_write_cmd_data(dots[i], OLED_DATA);
|
||||
oled_write_datas(&dots[0], 8);
|
||||
|
||||
OLED_DIsp_Set_Pos(x, y+1);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
//oled_write_cmd_data(dots[i+8], OLED_DATA);
|
||||
oled_write_datas(&dots[8], 8);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_String
|
||||
* 功能描述: 在指定位置显示字符串
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@str :要显示的字符串
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_String(int x, int y, char *str)
|
||||
{
|
||||
unsigned char j=0;
|
||||
while (str[j])
|
||||
{
|
||||
OLED_DIsp_Char(x, y, str[j]);//显示单个字符
|
||||
x += 8;
|
||||
if(x > 127)
|
||||
{
|
||||
x = 0;
|
||||
y += 2;
|
||||
}//移动显示位置
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_CHinese
|
||||
* 功能描述:在指定位置显示汉字
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@chr :要显示的汉字,三个汉字“百问网”中选择一个
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no)
|
||||
{
|
||||
unsigned char t,adder=0;
|
||||
OLED_DIsp_Set_Pos(x,y);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示上半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2], 1);
|
||||
adder+=1;
|
||||
}
|
||||
OLED_DIsp_Set_Pos(x,y+1);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示下半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2+1], 1);
|
||||
adder+=1;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Test
|
||||
* 功能描述: 整个屏幕显示测试
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Test(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OLED_DIsp_String(0, 0, "wiki.100ask.net");
|
||||
OLED_DIsp_String(0, 2, "book.100ask.net");
|
||||
OLED_DIsp_String(0, 4, "bbs.100ask.net");
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{ //显示汉字 百问网
|
||||
OLED_DIsp_CHinese(32+i*16, 6, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* spi_oled /dev/100ask_oled */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: %s /dev/100ask_oled\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd_spidev = open(argv[1], O_RDWR);
|
||||
if (fd_spidev < 0) {
|
||||
printf("open %s err\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ioctl(fd_spidev, OLED_IOC_INIT);
|
||||
|
||||
OLED_DIsp_Clear();
|
||||
|
||||
OLED_DIsp_Test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/spi_oled.h
Normal file
17
STM32MP157/source/A7/11_SPI/07_oled_use_mydrv/spi_oled.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _OLED_H_
|
||||
#define _OLED_H_
|
||||
|
||||
void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd);
|
||||
int oled_init(void);
|
||||
int oled_fill_data(unsigned char fill_Data);
|
||||
void OLED_DIsp_Clear(void);
|
||||
void OLED_DIsp_All(void);
|
||||
void OLED_DIsp_Set_Pos(int x, int y);
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c);
|
||||
void OLED_DIsp_String(int x, int y, char *str);
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no);
|
||||
void OLED_DIsp_Test();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
22
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/Makefile
Normal file
22
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
|
||||
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
|
||||
# 2.1 ARCH, 比如: export ARCH=arm64
|
||||
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
# 2.3 PATH, 比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
|
||||
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
|
||||
# 请参考各开发板的高级用户使用手册
|
||||
|
||||
KERN_DIR = /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4
|
||||
|
||||
all:
|
||||
make -C $(KERN_DIR) M=`pwd` modules
|
||||
$(CROSS_COMPILE)gcc -o spi_oled spi_oled.c
|
||||
|
||||
clean:
|
||||
make -C $(KERN_DIR) M=`pwd` modules clean
|
||||
rm -rf modules.order spi_oled
|
||||
|
||||
obj-m += oled_drv.o
|
||||
|
||||
|
||||
106
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/font.h
Normal file
106
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/font.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef _FONT_H_
|
||||
#define _FONT_H_
|
||||
const unsigned char oled_asc2_8x16[95][16]=
|
||||
{
|
||||
{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},//016
|
||||
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//117
|
||||
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},//218
|
||||
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},//319
|
||||
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},//420
|
||||
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},//521
|
||||
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},//622
|
||||
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},//723
|
||||
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},//824
|
||||
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},//925
|
||||
{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},//A33
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},//B34
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},//C35
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},//D36
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},//E37
|
||||
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},//F38
|
||||
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},//G39
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},//H40
|
||||
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//I41
|
||||
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},//J42
|
||||
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},//K43
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},//L44
|
||||
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},//M45
|
||||
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},//N46
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},//O47
|
||||
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},//P48
|
||||
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},//Q49
|
||||
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},//R50
|
||||
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},//S51
|
||||
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//T52
|
||||
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//U53
|
||||
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},//V54
|
||||
{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},//W55
|
||||
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},//X56
|
||||
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//Y57
|
||||
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},//Z58
|
||||
{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},//a65
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},//b66
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},//c67
|
||||
{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},//d68
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},//e69
|
||||
{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//f70
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},//g71
|
||||
{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//h72
|
||||
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//i73
|
||||
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},//j74
|
||||
{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},//k75
|
||||
{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//l76
|
||||
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},//m77
|
||||
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//n78
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//o79
|
||||
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},//p80
|
||||
{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},//q81
|
||||
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},//r82
|
||||
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},//s83
|
||||
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},//t84
|
||||
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},//u85
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},//v86
|
||||
{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},//w87
|
||||
{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},//x88
|
||||
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},//y89
|
||||
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},//z90
|
||||
{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
|
||||
};
|
||||
const unsigned char hz_1616[][32]={
|
||||
{0x02,0x00,0x02,0x00,0xE2,0xFF,0x22,0x42,0x22,0x42,0x32,0x42,0x2A,0x42,0x26,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0x22,0x42,0xE2,0xFF,0x02,0x00,0x02,0x00,0x00,0x00},/*"百",0*/
|
||||
{0x00,0x00,0xF8,0xFF,0x01,0x00,0x02,0x00,0x00,0x00,0xE2,0x1F,0x22,0x08,0x22,0x08,0x22,0x08,0xE2,0x1F,0x02,0x00,0x02,0x40,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"问",1*/
|
||||
{0x00,0x00,0xFE,0xFF,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x0E,0x02,0x10,0x22,0x08,0x42,0x06,0x82,0x01,0x72,0x4E,0x02,0x80,0xFE,0x7F,0x00,0x00,0x00,0x00},/*"网",2*/
|
||||
};
|
||||
#endif
|
||||
306
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/oled_drv.c
Normal file
306
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/oled_drv.c
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Simple synchronous userspace interface to SPI devices
|
||||
*
|
||||
* Copyright (C) 2006 SWAPP
|
||||
* Andrea Paterniani <a.paterniani@swapp-eng.it>
|
||||
* Copyright (C) 2007 David Brownell (simplification, cleanup)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
//为0 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct spi_device *oled;
|
||||
static int major;
|
||||
static struct gpio_desc *dc_gpio;
|
||||
|
||||
static void dc_pin_init(void)
|
||||
{
|
||||
gpiod_direction_output(dc_gpio, 1);
|
||||
}
|
||||
|
||||
static void oled_set_dc_pin(int val)
|
||||
{
|
||||
gpiod_set_value(dc_gpio, val);
|
||||
}
|
||||
|
||||
static void spi_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
spi_write(oled, buf, len);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: oled_write_cmd
|
||||
* 功能描述: oled向特定地址写入数据或者命令
|
||||
* 输入参数:@uc_data :要写入的数据
|
||||
@uc_cmd:为1则表示写入数据,为0表示写入命令
|
||||
* 输出参数:无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/04 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd)
|
||||
{
|
||||
if(uc_cmd==0)
|
||||
{
|
||||
oled_set_dc_pin(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
oled_set_dc_pin(1);//拉高,表示写入数据
|
||||
}
|
||||
spi_write_datas(&uc_data, 1);//写入
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: oled_init
|
||||
* 功能描述: oled_init的初始化,包括SPI控制器得初始化
|
||||
* 输入参数:无
|
||||
* 输出参数: 初始化的结果
|
||||
* 返 回 值: 成功则返回0,否则返回-1
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static int oled_init(void)
|
||||
{
|
||||
oled_write_cmd_data(0xae,OLED_CMD);//关闭显示
|
||||
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//设置 lower column address
|
||||
oled_write_cmd_data(0x10,OLED_CMD);//设置 higher column address
|
||||
|
||||
oled_write_cmd_data(0x40,OLED_CMD);//设置 display start line
|
||||
|
||||
oled_write_cmd_data(0xB0,OLED_CMD);//设置page address
|
||||
|
||||
oled_write_cmd_data(0x81,OLED_CMD);// contract control
|
||||
oled_write_cmd_data(0x66,OLED_CMD);//128
|
||||
|
||||
oled_write_cmd_data(0xa1,OLED_CMD);//设置 segment remap
|
||||
|
||||
oled_write_cmd_data(0xa6,OLED_CMD);//normal /reverse
|
||||
|
||||
oled_write_cmd_data(0xa8,OLED_CMD);//multiple ratio
|
||||
oled_write_cmd_data(0x3f,OLED_CMD);//duty = 1/64
|
||||
|
||||
oled_write_cmd_data(0xc8,OLED_CMD);//com scan direction
|
||||
|
||||
oled_write_cmd_data(0xd3,OLED_CMD);//set displat offset
|
||||
oled_write_cmd_data(0x00,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd5,OLED_CMD);//set osc division
|
||||
oled_write_cmd_data(0x80,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xd9,OLED_CMD);//ser pre-charge period
|
||||
oled_write_cmd_data(0x1f,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xda,OLED_CMD);//set com pins
|
||||
oled_write_cmd_data(0x12,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xdb,OLED_CMD);//set vcomh
|
||||
oled_write_cmd_data(0x30,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0x8d,OLED_CMD);//set charge pump disable
|
||||
oled_write_cmd_data(0x14,OLED_CMD);//
|
||||
|
||||
oled_write_cmd_data(0xaf,OLED_CMD);//set dispkay on
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
static void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{ oled_write_cmd_data(0xb0+y,OLED_CMD);
|
||||
oled_write_cmd_data((x&0x0f),OLED_CMD);
|
||||
oled_write_cmd_data(((x&0xf0)>>4)|0x10,OLED_CMD);
|
||||
}
|
||||
|
||||
|
||||
static long
|
||||
spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
/* 根据cmd操作硬件 */
|
||||
switch (cmd)
|
||||
{
|
||||
case OLED_IOC_INIT: /* init */
|
||||
{
|
||||
dc_pin_init();
|
||||
oled_init();
|
||||
break;
|
||||
}
|
||||
|
||||
case OLED_IOC_SET_POS: /* set pos */
|
||||
{
|
||||
x = arg & 0xff;
|
||||
y = (arg >> 8) & 0xff;
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
spidev_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *f_pos)
|
||||
{
|
||||
char *ker_buf;
|
||||
int err;
|
||||
|
||||
ker_buf = kmalloc(count, GFP_KERNEL);
|
||||
err = copy_from_user(ker_buf, buf, count);
|
||||
|
||||
oled_set_dc_pin(1);//拉高,表示写入数据
|
||||
spi_write_datas(ker_buf, count);
|
||||
kfree(ker_buf);
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations spidev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
/* REVISIT switch to aio primitives, so that userspace
|
||||
* gets more complete API coverage. It'll simplify things
|
||||
* too, except for the locking.
|
||||
*/
|
||||
.write = spidev_write,
|
||||
.unlocked_ioctl = spidev_ioctl,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* The main reason to have this class is to make mdev/udev create the
|
||||
* /dev/spidevB.C character device nodes exposing our userspace API.
|
||||
* It also simplifies memory management.
|
||||
*/
|
||||
|
||||
static struct class *spidev_class;
|
||||
|
||||
static const struct of_device_id spidev_dt_ids[] = {
|
||||
{ .compatible = "100ask,oled" },
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int spidev_probe(struct spi_device *spi)
|
||||
{
|
||||
/* 1. 记录spi_device */
|
||||
oled = spi;
|
||||
|
||||
/* 2. 注册字符设备 */
|
||||
major = register_chrdev(0, "100ask_oled", &spidev_fops);
|
||||
spidev_class = class_create(THIS_MODULE, "100ask_oled");
|
||||
device_create(spidev_class, NULL, MKDEV(major, 0), NULL, "100ask_oled");
|
||||
|
||||
/* 3. 获得GPIO引脚 */
|
||||
dc_gpio = gpiod_get(&spi->dev, "dc", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spidev_remove(struct spi_device *spi)
|
||||
{
|
||||
gpiod_put(dc_gpio);
|
||||
|
||||
/* 反注册字符设备 */
|
||||
device_destroy(spidev_class, MKDEV(major, 0));
|
||||
class_destroy(spidev_class);
|
||||
unregister_chrdev(major, "100ask_oled");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver spidev_spi_driver = {
|
||||
.driver = {
|
||||
.name = "100ask_spi_oled_drv",
|
||||
.of_match_table = of_match_ptr(spidev_dt_ids),
|
||||
},
|
||||
.probe = spidev_probe,
|
||||
.remove = spidev_remove,
|
||||
|
||||
/* NOTE: suspend/resume methods are not necessary here.
|
||||
* We don't do anything except pass the requests to/from
|
||||
* the underlying controller. The refrigerator handles
|
||||
* most issues; the controller driver handles the rest.
|
||||
*/
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init spidev_init(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = spi_register_driver(&spidev_spi_driver);
|
||||
if (status < 0) {
|
||||
}
|
||||
return status;
|
||||
}
|
||||
module_init(spidev_init);
|
||||
|
||||
static void __exit spidev_exit(void)
|
||||
{
|
||||
spi_unregister_driver(&spidev_spi_driver);
|
||||
}
|
||||
module_exit(spidev_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
241
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/spi_oled.c
Normal file
241
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/spi_oled.c
Normal file
@@ -0,0 +1,241 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "font.h"
|
||||
|
||||
#define OLED_IOC_INIT 123
|
||||
#define OLED_IOC_SET_POS 124
|
||||
|
||||
|
||||
//为0 表示命令,为1表示数据
|
||||
#define OLED_CMD 0
|
||||
#define OLED_DATA 1
|
||||
|
||||
static int fd_spidev;
|
||||
static int dc_pin_num;
|
||||
|
||||
|
||||
void OLED_DIsp_Set_Pos(int x, int y);
|
||||
|
||||
void oled_write_datas(const unsigned char *buf, int len)
|
||||
{
|
||||
write(fd_spidev, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Clear
|
||||
* 功能描述: 整个屏幕显示数据清0
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Clear(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_All
|
||||
* 功能描述: 整个屏幕显示全部点亮,可以用于检查坏点
|
||||
* 输入参数:无
|
||||
* 输出参数:无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_All(void)
|
||||
{
|
||||
unsigned char x, y;
|
||||
char buf[128];
|
||||
|
||||
memset(buf, 0xff, 128);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
OLED_DIsp_Set_Pos(0, y);
|
||||
oled_write_datas(buf, 128);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//坐标设置
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Set_Pos
|
||||
* 功能描述:设置要显示的位置
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Set_Pos(int x, int y)
|
||||
{
|
||||
ioctl(fd_spidev, OLED_IOC_SET_POS, x | (y << 8));
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Char
|
||||
* 功能描述:在某个位置显示字符 1-9
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@c :要显示的字符的ascii码
|
||||
* 输出参数: 无
|
||||
* 返 回 值:
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c)
|
||||
{
|
||||
int i = 0;
|
||||
/* 得到字模 */
|
||||
const unsigned char *dots = oled_asc2_8x16[c - ' '];
|
||||
|
||||
/* 发给OLED */
|
||||
OLED_DIsp_Set_Pos(x, y);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
// oled_write_cmd_data(dots[i], OLED_DATA);
|
||||
oled_write_datas(&dots[0], 8);
|
||||
|
||||
OLED_DIsp_Set_Pos(x, y+1);
|
||||
/* 发出8字节数据 */
|
||||
//for (i = 0; i < 8; i++)
|
||||
//oled_write_cmd_data(dots[i+8], OLED_DATA);
|
||||
oled_write_datas(&dots[8], 8);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_String
|
||||
* 功能描述: 在指定位置显示字符串
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@str :要显示的字符串
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_String(int x, int y, char *str)
|
||||
{
|
||||
unsigned char j=0;
|
||||
while (str[j])
|
||||
{
|
||||
OLED_DIsp_Char(x, y, str[j]);//显示单个字符
|
||||
x += 8;
|
||||
if(x > 127)
|
||||
{
|
||||
x = 0;
|
||||
y += 2;
|
||||
}//移动显示位置
|
||||
j++;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_CHinese
|
||||
* 功能描述:在指定位置显示汉字
|
||||
* 输入参数:@ x :要显示的column address
|
||||
@y :要显示的page address
|
||||
@chr :要显示的汉字,三个汉字“百问网”中选择一个
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no)
|
||||
{
|
||||
unsigned char t,adder=0;
|
||||
OLED_DIsp_Set_Pos(x,y);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示上半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2], 1);
|
||||
adder+=1;
|
||||
}
|
||||
OLED_DIsp_Set_Pos(x,y+1);
|
||||
for(t=0;t<16;t++)
|
||||
{//显示下半截字符
|
||||
oled_write_datas(&hz_1616[no][t*2+1], 1);
|
||||
adder+=1;
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* 函数名称: OLED_DIsp_Test
|
||||
* 功能描述: 整个屏幕显示测试
|
||||
* 输入参数:无
|
||||
* 输出参数: 无
|
||||
* 返 回 值: 无
|
||||
* 修改日期 版本号 修改人 修改内容
|
||||
* -----------------------------------------------
|
||||
* 2020/03/15 V1.0 芯晓 创建
|
||||
***********************************************************************/
|
||||
void OLED_DIsp_Test(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
OLED_DIsp_String(0, 0, "wiki.100ask.net");
|
||||
OLED_DIsp_String(0, 2, "book.100ask.net");
|
||||
OLED_DIsp_String(0, 4, "bbs.100ask.net");
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{ //显示汉字 百问网
|
||||
OLED_DIsp_CHinese(32+i*16, 6, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* spi_oled /dev/100ask_oled */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("Usage: %s /dev/100ask_oled\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd_spidev = open(argv[1], O_RDWR);
|
||||
if (fd_spidev < 0) {
|
||||
printf("open %s err\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ioctl(fd_spidev, OLED_IOC_INIT);
|
||||
|
||||
OLED_DIsp_Clear();
|
||||
|
||||
OLED_DIsp_Test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/spi_oled.h
Normal file
17
STM32MP157/source/A7/11_SPI/08_oled_use_mydrv_ok/spi_oled.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _OLED_H_
|
||||
#define _OLED_H_
|
||||
|
||||
void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd);
|
||||
int oled_init(void);
|
||||
int oled_fill_data(unsigned char fill_Data);
|
||||
void OLED_DIsp_Clear(void);
|
||||
void OLED_DIsp_All(void);
|
||||
void OLED_DIsp_Set_Pos(int x, int y);
|
||||
void OLED_DIsp_Char(int x, int y, unsigned char c);
|
||||
void OLED_DIsp_String(int x, int y, char *str);
|
||||
void OLED_DIsp_CHinese(unsigned char x,unsigned char y,unsigned char no);
|
||||
void OLED_DIsp_Test();
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user