5. EXAMPLE CODE OF MODULE USAGE BY USER LAYER
Please ensure the driver has enabled in menuconfig and device tree has correct setting.
5.1 GPIO Module
5.1.1 GPIO Module control by C code
/************************************************************/
//File name:gpiotest.c
//Function : Test linux gpio with SP7021
//Date : 2019-12-19
/************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<dirent.h>
#define SYS_GPIO_PFX "/sys/class/gpio/"
#define PIN_DIR_I 0
#define PIN_DIR_O 1
typedef unsigned char uint8;
int fd = -1;
//gpio init
static uint8 gpio_init(int _pin)
{
DIR *dp;
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
printf("port=%d, num=%d \n",port,num);
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d", port, num);
if(!(dp=opendir(fpath)))
{
FILE *fp;
if((fp = fopen(SYS_GPIO_PFX"export", "w")) == NULL) return(-1);
fprintf(fp, "%d", _pin);
fclose(fp);
}
else
{
closedir(dp);
}
return(0);
}
static uint8 gpio_read(int _pin)
{
char ret, ss[2];
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/value", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
ret = read(fd, ss, 1);
close(fd);
if(ret < 0) return(0);
return((ss[0] == '0'?0:1));
}
static uint8 gpio_write(int _pin, int _val)
{
int ret;
char x[2];
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/value", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
x[1] = '\0';
x[0] = (_val>0 ? '1':'0');
ret = write(fd, x, 1);
close(fd);
return(ret);
}
static uint8 gpio_dir_get(int _pin)
{
static char ss[2];
char fpath[100];
int ret,port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/direction", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
ret = read(fd, ss, 2);
close(fd);
if(ret < 0) return(0);
return((ss[0] == 'i'? PIN_DIR_I:PIN_DIR_O));
}
static uint8 gpio_dir_set(int _pin, int _dir)
{
int ret=0;
const char *ss="in";
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/direction", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
if(_dir == PIN_DIR_O) ss="out";
ret = write(fd, ss, strlen(ss)*sizeof(char));
close(fd);
return((ret<2 ? -1:0));
}
// main
// $ ./gpiotest 10 state ==> get G_MX[10] direction
// $ ./gpiotest 10 out ==> set G_MX[10] as output
// $ ./gpiotest 10 read ==> read G_MX[10] value
// $ ./gpiotest 10 write 1 ==> mean set G_MX[10] to high
int main(int argc, char *argv[])
{
int i,pinnum,value;
printf("GPIO test main start \n");
pinnum = atoi(argv[1]);
if (argv[3] != NULL)
value = atoi(argv[3]);
gpio_init(pinnum);
if(strcmp(argv[2],"state") == 0)
{
printf("state:%s \n", (gpio_dir_get(pinnum) == PIN_DIR_I? "IN":"OUT"));
}
if(strcmp(argv[2],"in") == 0)
{
printf("set IN ok:%d \n", gpio_dir_set(pinnum,PIN_DIR_I));
}
if(strcmp(argv[2],"read") == 0)
{
printf("read:%d \n", gpio_read(pinnum));
sleep(5);
printf("read:%d \n", gpio_read(pinnum));
}
if(strcmp(argv[2],"out") == 0)
{
printf("set OUT ok:%d \n", gpio_dir_set(pinnum,PIN_DIR_O));
}
if(strcmp(argv[2],"write") == 0)
{
printf("set OUT ok:%d \n", gpio_dir_set(pinnum,PIN_DIR_O));
if(value == 1)
printf("write done:%d \n", gpio_write(pinnum,1));
else
printf("write done:%d \n", gpio_write(pinnum,0));
}
printf("GPIO test end! \n ");
for(i=1; i; i--){
usleep(1000*100);
}
}
5.1.2 GPIO Module control by Python code
5.1.2.1 Edit gpio.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>
#define SYS_GPIO_PFX "/sys/class/gpio/"
#define PIN_DIR_I 0
#define PIN_DIR_O 1
typedef unsigned char uint8;
int fd = -1;
uint8 gpio_init(int);
uint8 gpio_read(int);
uint8 gpio_write(int, int);
uint8 gpio_dir_get(int);
uint8 gpio_dir_set(int, int);
//gpio init
uint8 gpio_init(int _pin)
{
DIR *dp;
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
printf("port=%d, num=%d \n",port,num);
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d", port, num);
if(!(dp=opendir(fpath)))
{
FILE *fp;
if((fp = fopen(SYS_GPIO_PFX"export", "w")) == NULL) return(-1);
fprintf(fp, "%d", _pin);
fclose(fp);
sprintf(fpath, "sudo -S chmod 777 %sP%d_0%d/value", SYS_GPIO_PFX, port, num);
printf ("fpath0=%s", fpath);
system(fpath);
//chmod(fpath, 0777);
sprintf(fpath, "sudo -S chmod 777 %sP%d_0%d/direction", SYS_GPIO_PFX, port, num);
printf ("fpath1=%s", fpath);
system(fpath);
//chmod(fpath, 0777);
}
else
{
closedir(dp);
}
return(0);
}
uint8 gpio_read(int _pin)
{
char ret, ss[2];
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/value", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
ret = read(fd, ss, 1);
close(fd);
if(ret < 0) return(0);
return((ss[0] == '0'?0:1));
}
uint8 gpio_write(int _pin, int _val)
{
int ret;
char x[2];
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/value", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
x[1] = '\0';
x[0] = (_val>0 ? '1':'0');
ret = write(fd, x, 1);
close(fd);
return(ret);
}
uint8 gpio_dir_get(int _pin)
{
static char ss[2];
char fpath[100];
int ret,port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/direction", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
ret = read(fd, ss, 2);
close(fd);
if(ret < 0) return(0);
return((ss[0] == 'i'? PIN_DIR_I:PIN_DIR_O));
}
uint8 gpio_dir_set(int _pin, int _dir)
{
int ret=0;
const char *ss="in";
char fpath[100];
int port,num;
port = _pin/8;
num = _pin%8;
sprintf(fpath, SYS_GPIO_PFX"P%d_0%d/direction", port, num);
printf("fpath=%s \n", fpath);
fd = open(fpath, O_RDWR); // open file and enable read and write
if(fd < 0)
{
perror("Can't open gpio file \n"); // open i2c dev file fail
exit(1);
}
printf("open gpio file success !\n"); // open i2c dev file succes
if(_dir == PIN_DIR_O) ss="out";
ret = write(fd, ss, strlen(ss)*sizeof(char));
close(fd);
return((ret<2 ? -1:0));
}
5.1.2.2 Edit share library
$ gcc -shared -fPIC gpio.c -o gpio.so
5.1.2.3 Edit gpio.py
import time
from ctypes import *
m=cdll.LoadLibrary('./gpio.so')
k=m.gpio_init(c_int(12))
print(k)
k=m.gpio_dir_set(c_int(12),c_int(1))
print(k)
while True:
k=m.gpio_write(c_int(12),c_int(1))
time.sleep(0.005)
k=m.gpio_write(c_int(12),c_int(0))
time.sleep(0.005)
5.2 I2C Module
/************************************************************/
//File name:tea5767.c
//Function : Test linux i2c with tea5767 communication
//Date : 2019-05-29
/************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/select.h>
#include<sys/time.h>
#include<errno.h>
#define Address 0x60 //tea5767 ID address
#define I2C_RETRIES 0x0701
#define I2C_TIMEOUT 0x0702
#define I2C_SLAVE 0x0703
#define I2C_BUS_MODE 0x0780
typedef unsigned char uint8;
int fd = -1;
//Function declare
static uint8 tea5767_Init(void);
//tea5767 init
static uint8 tea5767_Init(void)
{
float frequency;
unsigned div;
uint8 data[5];
printf(" TEA5767 init\n ");
fd = open("/dev/i2c-0", O_RDWR); // open file of i2c-0 and enable read and write
if(fd < 0) {
perror("Can't open /dev/TEA5767 \n"); // open i2c dev file fail
exit(1);
}
printf("open /dev/i2c-0 success !\n"); // open i2c dev file succes
if(ioctl(fd, I2C_SLAVE, Address)<0) { //set i2c address
printf("fail to set i2c device slave address!\n");
close(fd);
return -1;
}
printf("set slave address to 0x%x success!\n", Address);
frequency = 97.5;
div = (4 * (frequency * 1000 + 225))/32.768;
data[0] = (div >> 8)&0x3f ;
data[1] = div & 0xff ;
data[2] = 0xB0 ;
data[3] = 0x50 ;
data[4] = 0x00 ;
write(fd, data, 5);
read(fd, data, 5);
printf("data0=0x%x\n", data[0]);
printf("data1=0x%x\n", data[1]);
printf("data2=0x%x\n", data[2]);
printf("data3=0x%x\n", data[3]);
printf("data4=0x%x\n", data[4]);
return(1);
}
// main
int main(int argc, char *argv[])
{
int i;
tea5767_Init();
usleep(1000*100);
printf(" TEA5767 get \n ");
close(fd);
}
5.3 SPI Module
/************************************************************/
//File name : ms5611.c
//Function : Test linux SPI with ms5611 communication
//Date : 2019-05-29
/************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <tgmath.h>
#include <math.h>
#include <fcntl.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#define DIG_START 0x88
#define TEMP_START 0xFA
#define CTRL_MEAS 0xF4
#define TEMP_ONLY_NORMAL_MODE 0xE3 // 111 000 11
#define MS5611_CMD_ADC_READ (0x00)
#define MS5611_CMD_RESET (0x1E)
#define MS5611_CMD_CONV_D1_256 (0x40)
#define MS5611_CMD_CONV_D1_512 (0x42)
#define MS5611_CMD_CONV_D1_1024 (0x44)
#define MS5611_CMD_CONV_D1_2048 (0x46)
#define MS5611_CMD_CONV_D1_4096 (0x48)
#define MS5611_CMD_CONV_D2_256 (0x50)
#define MS5611_CMD_CONV_D2_512 (0x52)
#define MS5611_CMD_CONV_D2_1024 (0x54)
#define MS5611_CMD_CONV_D2_2048 (0x56)
#define MS5611_CMD_CONV_D2_4096 (0x58)
#define MS5611_CMD_READ_PROM_RESERVE (0xA0)
#define MS5611_CMD_READ_PROM_1 (0xA2)
#define MS5611_CMD_READ_PROM_2 (0xA4)
#define MS5611_CMD_READ_PROM_3 (0xA6)
#define MS5611_CMD_READ_PROM_4 (0xA8)
#define MS5611_CMD_READ_PROM_5 (0xAA)
#define MS5611_CMD_READ_PROM_6 (0xAC)
#define MS5611_CMD_READ_PROM_CRC (0xAE)
char buf[10];
char buf2[10];
struct spi_ioc_transfer xfer[10];
spi_init(int file)
{
__u8 lsb = 0;
__u8 mode = 0;
__u8 bits = 8;
__u32 speed = 20000000;
if (ioctl(file, SPI_IOC_RD_MODE, &mode) < 0) {
perror("SPI rd_mode");
return;
}
if (ioctl(file, SPI_IOC_WR_MAX_SPEED_HZ, &speed)<0) {
perror("can't set max speed hz");
return;
}
if (ioctl(file, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
perror("SPI max_speed_hz");
return;
}
printf("spi max_speed_hz: %d\n", speed);
}
char * spi_rw(int addr,int nbytes,int file)
{
int status;
memset(buf, 0, sizeof buf);
memset(buf2, 0, sizeof buf2);
buf[0] = addr;
xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = 1;
xfer[1].rx_buf = (unsigned long) buf2;
xfer[1].len = nbytes;
printf("spi_start_rw\n");
status = ioctl(file, SPI_IOC_MESSAGE(2), xfer);
if (status < 0) {
perror("SPI_IOC_MESSAGE");
return;
}
return buf2;
}
char * spi_read(int addr,int nbytes,int file)
{
int status;
memset(buf, 0, sizeof buf);
memset(buf2, 0, sizeof buf2); buf[0] = addr | 128; xfer[0].tx_buf = (unsigned long)buf; xfer[0].len = 1; xfer[1].rx_buf = (unsigned long) buf2; xfer[1].len = nbytes; printf("before buf[0] = 0x0%x\n" ,buf[0]); status = ioctl(file, SPI_IOC_MESSAGE(2), xfer); if (status < 0) { perror("SPI_IOC_MESSAGE"); return; } return buf2;} void spi_write_com(char value, int file){ int status;