Touchscreen driver POC

Example documentation
This commit is contained in:
2026-05-07 16:28:08 -07:00
parent c0ad8306a7
commit a125f45b34
201 changed files with 19783 additions and 34 deletions
@@ -0,0 +1,342 @@
/*****************************************************************************
* | File : DEV_Config.c
* | Author : Waveshare team
* | Function : Hardware underlying interface
* | Info :
*----------------
* | This version: V2.0
* | Date : 2020-06-17
* | Info : Basic version
*
******************************************************************************/
#include "DEV_Config.h"
#include <unistd.h>
#include <fcntl.h>
#if USE_LGPIO_LIB
int GPIO_Handle;
int SPI_Handle;
int IIC_Handle;
#endif
/**
* GPIO
**/
int EPD_RST_PIN;
int EPD_DC_PIN;
int EPD_CS_PIN;
int EPD_BUSY_PIN;
int IIC_Address;
uint32_t fd;
/*****************************************
GPIO
*****************************************/
void DEV_Digital_Write(UWORD Pin, UBYTE Value)
{
#ifdef USE_BCM2835_LIB
bcm2835_gpio_write(Pin, Value);
#elif USE_WIRINGPI_LIB
digitalWrite(Pin, Value);
#elif USE_LGPIO_LIB
lgGpioWrite(GPIO_Handle, Pin, Value);
#elif USE_GPIOD_LIB
GPIOD_Write(Pin, Value);
#endif
}
UBYTE DEV_Digital_Read(UWORD Pin)
{
UBYTE Read_value = 0;
#ifdef USE_BCM2835_LIB
Read_value = bcm2835_gpio_lev(Pin);
#elif USE_WIRINGPI_LIB
Read_value = digitalRead(Pin);
#elif USE_LGPIO_LIB
Read_value = lgGpioRead(GPIO_Handle,Pin);
#elif USE_GPIOD_LIB
Read_value = GPIOD_Read(Pin);
#endif
return Read_value;
}
void DEV_GPIO_Mode(UWORD Pin, UWORD Mode)
{
#ifdef USE_BCM2835_LIB
if(Mode == 0 || Mode == BCM2835_GPIO_FSEL_INPT){
bcm2835_gpio_fsel(Pin, BCM2835_GPIO_FSEL_INPT);
}else {
bcm2835_gpio_fsel(Pin, BCM2835_GPIO_FSEL_OUTP);
}
#elif USE_WIRINGPI_LIB
if(Mode == 0 || Mode == INPUT) {
pinMode(Pin, INPUT);
pullUpDnControl(Pin, PUD_UP);
} else {
pinMode(Pin, OUTPUT);
// Debug (" %d OUT \r\n",Pin);
}
#elif USE_LGPIO_LIB
if(Mode == 0 || Mode == LG_SET_INPUT){
lgGpioClaimInput(GPIO_Handle,LFLAGS,Pin);
// Debug("IN Pin = %d\r\n",Pin);
}else{
lgGpioClaimOutput(GPIO_Handle, LFLAGS, Pin, LG_LOW);
// Debug("OUT Pin = %d\r\n",Pin);
}
#elif USE_GPIOD_LIB
if(Mode == 0 || Mode == GPIOD_IN){
GPIOD_Direction(Pin, GPIOD_IN);
// Debug("IN Pin = %d\r\n",Pin);
}else{
GPIOD_Direction(Pin, GPIOD_OUT);
// Debug("OUT Pin = %d\r\n",Pin);
}
#endif
}
/**
* delay x ms
**/
void DEV_Delay_ms(UDOUBLE xms)
{
#ifdef USE_BCM2835_LIB
bcm2835_delay(xms);
#elif USE_WIRINGPI_LIB
delay(xms);
#elif USE_LGPIO_LIB
lguSleep(xms/1000.0);
#elif USE_GPIOD_LIB
UDOUBLE i;
for(i=0; i < xms; i++){
usleep(1000);
}
#endif
}
static void DEV_GPIO_Init(void)
{
EPD_RST_PIN = 17;
EPD_DC_PIN = 25;
EPD_CS_PIN = 8;
EPD_BUSY_PIN = 24;
DEV_GPIO_Mode(EPD_RST_PIN, 1);
DEV_GPIO_Mode(EPD_DC_PIN, 1);
DEV_GPIO_Mode(EPD_CS_PIN, 1);
DEV_GPIO_Mode(EPD_BUSY_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 1);
DEV_GPIO_Mode(TRST, 1);
DEV_GPIO_Mode(INT, 0);
}
/******************************************************************************
function: Module Initialize, the library and initialize the pins, SPI protocol
parameter:
Info:
******************************************************************************/
UBYTE DEV_ModuleInit(void)
{
#ifdef USE_BCM2835_LIB
if(!bcm2835_init()) {
printf("bcm2835 init failed !!! \r\n");
return 1;
} else {
printf("bcm2835 init success !!! \r\n");
}
DEV_GPIO_Init();
bcm2835_i2c_begin();
bcm2835_i2c_setSlaveAddress(IIC_Address);
// bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
bcm2835_spi_begin(); //Start spi interface, set spi pin for the reuse function
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); //High first transmission
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); //spi mode 0
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32); //Frequency
bcm2835_spi_chipSelect(BCM2835_SPI_CS0); //set CE0
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); //enable cs0
#elif USE_WIRINGPI_LIB
// if(wiringPiSetup() < 0) {//use wiringpi Pin number table
if(wiringPiSetupGpio() < 0) { //use BCM2835 Pin number table
printf("set wiringPi lib failed !!! \r\n");
return 1;
} else {
printf("set wiringPi lib success !!! \r\n");
}
// GPIO Config
DEV_GPIO_Init();
// wiringPiSPISetup(0,10000000);
wiringPiSPISetupMode(0, 10000000, 0);
fd = wiringPiI2CSetup(IIC_Address);
DEV_HARDWARE_I2C_begin("/dev/i2c-1");
DEV_HARDWARE_I2C_setSlaveAddress(IIC_Address);
#elif USE_LGPIO_LIB
char buffer[NUM_MAXBUF];
FILE *fp;
fp = popen("cat /proc/cpuinfo | grep 'Raspberry Pi 5'", "r");
if (fp == NULL) {
Debug("It is not possible to determine the model of the Raspberry PI\n");
return -1;
}
if(fgets(buffer, sizeof(buffer), fp) != NULL)
{
GPIO_Handle = lgGpiochipOpen(4);
if (GPIO_Handle < 0)
{
Debug( "gpiochip4 Export Failed\n");
return -1;
}
}
else
{
GPIO_Handle = lgGpiochipOpen(0);
if (GPIO_Handle < 0)
{
Debug( "gpiochip0 Export Failed\n");
return -1;
}
}
SPI_Handle = lgSpiOpen(0, 0, 10000000, 0);
IIC_Handle = lgI2cOpen(1,IIC_Address,0);
DEV_GPIO_Init();
#elif USE_GPIOD_LIB
GPIOD_Export();
DEV_GPIO_Init();
DEV_HARDWARE_I2C_begin("/dev/i2c-1");
DEV_HARDWARE_I2C_setSlaveAddress(IIC_Address);
DEV_HARDWARE_SPI_begin("/dev/spidev0.0");
DEV_HARDWARE_SPI_setSpeed(10000000);
#endif
return 0;
}
/**
* SPI
**/
void DEV_SPI_WriteByte(uint8_t Value)
{
#ifdef USE_BCM2835_LIB
bcm2835_spi_transfer(Value);
#elif USE_WIRINGPI_LIB
wiringPiSPIDataRW(0, &Value, 1);
#elif USE_LGPIO_LIB
lgSpiWrite(SPI_Handle,(char*)&Value, 1);
#elif USE_GPIOD_LIB
DEV_HARDWARE_SPI_TransferByte(Value);
#endif
}
void DEV_SPI_Write_nByte(uint8_t *pData, uint32_t Len)
{
#ifdef USE_BCM2835_LIB
char rData[Len];
bcm2835_spi_transfernb(pData, rData, Len);
#elif USE_WIRINGPI_LIB
wiringPiSPIDataRW(0, pData, Len);
#elif USE_LGPIO_LIB
lgSpiWrite(SPI_Handle,(char*)pData, Len);
#elif USE_GPIOD_LIB
DEV_HARDWARE_SPI_Transfer(pData, Len);
#endif
}
UBYTE I2C_Write_Byte(UWORD Reg, char *Data, UBYTE len)
{
char wbuf[50]={(Reg>>8)&0xff, Reg&0xff};
for(UBYTE i=0; i<len; i++) {
wbuf[i+2] = Data[i];
}
#ifdef USE_BCM2835_LIB
if(bcm2835_i2c_write(wbuf, len+2) != BCM2835_I2C_REASON_OK) {
printf("WRITE ERROR \r\n");
return -1;
}
#elif USE_WIRINGPI_LIB
if(len > 1)
printf("wiringPi I2C WARING \r\n");
wiringPiI2CWriteReg16(fd, wbuf[0], wbuf[1] | (wbuf[2]<<8));
#elif USE_LGPIO_LIB
lgI2cWriteDevice(IIC_Handle, wbuf, len+2);
#elif USE_GPIOD_LIB
DEV_HARDWARE_I2C_write(wbuf, len+2);
#endif
return 0;
}
#ifdef USE_WIRINGPI_LIB
static I2C_Write_WiringPi(UWORD Reg)
{
wiringPiI2CWriteReg8(fd, (Reg>>8) & 0xff, Reg & 0xff);
}
#endif
UBYTE I2C_Read_Byte(UWORD Reg, char *Data, UBYTE len)
{
char *rbuf = Data;
#ifdef USE_BCM2835_LIB
I2C_Write_Byte(Reg, 0, 0);
if(bcm2835_i2c_read(rbuf, len) != BCM2835_I2C_REASON_OK) {
printf("READ ERROR \r\n");
return -1;
}
#elif USE_WIRINGPI_LIB
I2C_Write_WiringPi(Reg);
for(UBYTE i=0; i<len; i++) {
rbuf[i] = wiringPiI2CRead(fd);
}
#elif USE_LGPIO_LIB
I2C_Write_Byte(Reg, 0, 0);
lgI2cReadDevice(IIC_Handle, rbuf, len);
#elif USE_GPIOD_LIB
I2C_Write_Byte(Reg, 0, 0);
DEV_HARDWARE_I2C_read(rbuf, len);
#endif
return 0;
}
/******************************************************************************
function: Module exits, closes SPI and BCM2835 library
parameter:
Info:
******************************************************************************/
void DEV_ModuleExit(void)
{
TRST_0;
DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_RST_PIN, 0);
#ifdef USE_BCM2835_LIB
bcm2835_i2c_end();
bcm2835_spi_end();
bcm2835_close();
#elif USE_WIRINGPI_LIB
#elif USE_LGPIO_LIB
lgI2cClose(IIC_Handle);
lgSpiClose(SPI_Handle);
lgGpiochipClose(GPIO_Handle);
#elif USE_GPIOD_LIB
DEV_HARDWARE_I2C_end();
DEV_HARDWARE_SPI_end();
GPIOD_Unexport(EPD_CS_PIN);
GPIOD_Unexport(EPD_DC_PIN);
GPIOD_Unexport(EPD_RST_PIN);
GPIOD_Unexport(EPD_BUSY_PIN);
GPIOD_Unexport_GPIO();
#endif
}
@@ -0,0 +1,78 @@
#ifndef _DEV_CONFIG_H_
#define _DEV_CONFIG_H_
/***********************************************************************************************************************
------------------------------------------------------------------------
|\\\ ///|
|\\\ Hardware interface ///|
------------------------------------------------------------------------
***********************************************************************************************************************/
#ifdef USE_BCM2835_LIB
#include <bcm2835.h>
#elif USE_WIRINGPI_LIB
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <wiringPiI2C.h>
#include "dev_hardware_i2c.h"
#elif USE_LGPIO_LIB
#include <lgpio.h>
#define LFLAGS 0
#define NUM_MAXBUF 4
#elif USE_GPIOD_LIB
#include "RPI_gpiod.h"
#include "dev_hardware_i2c.h"
#include "dev_hardware_SPI.h"
#endif
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "Debug.h"
// #define IIC_Address 0x14
// #define IIC_Address_Read 0x29
// #define IIC_Address_Write 0x28
/**
* data
**/
#define UBYTE uint8_t
#define UWORD uint16_t
#define UDOUBLE uint32_t
//TP Define
#define TRST 22
#define INT 27
#define TRST_0 DEV_Digital_Write(TRST, 0)
#define TRST_1 DEV_Digital_Write(TRST, 1)
#define INT_0 DEV_Digital_Write(INT, 0)
#define INT_1 DEV_Digital_Write(INT, 1)
/**
* GPIOI config
**/
extern int EPD_RST_PIN;
extern int EPD_DC_PIN;
extern int EPD_CS_PIN;
extern int EPD_BUSY_PIN;
/*------------------------------------------------------------------------------------------------------*/
UBYTE DEV_ModuleInit(void);
void DEV_ModuleExit(void);
void DEV_GPIO_Mode(UWORD Pin, UWORD Mode);
void DEV_Delay_ms(UDOUBLE xms);
void DEV_Digital_Write(UWORD Pin, UBYTE Value);
UBYTE DEV_Digital_Read(UWORD Pin);
void DEV_SPI_WriteByte(UBYTE Value);
void DEV_SPI_Write_nByte(uint8_t *pData, uint32_t Len);
UBYTE I2C_Write_Byte(UWORD Reg, char *Data, UBYTE len);
UBYTE I2C_Read_Byte(UWORD Reg, char *Data, UBYTE len);
#endif
@@ -0,0 +1,47 @@
/*****************************************************************************
* | File : Debug.h
* | Author : Waveshare team
* | Function : debug with printf
* | Info :
* Image scanning
* Please use progressive scanning to generate images or fonts
*----------------
* | This version: V2.0
* | Date : 2020-06-17
* | Info :
* 1.USE_DEBUG -> DEBUG, If you need to see the debug information,
* clear the execution: make DEBUG=-DDEBUG
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#ifndef __DEBUG_H
#define __DEBUG_H
#include <stdio.h>
#if 1
#define Debug(__info,...) printf("Debug: " __info,##__VA_ARGS__)
#else
#define Debug(__info,...)
#endif
#endif
@@ -0,0 +1,170 @@
/*****************************************************************************
* | File : RPI_GPIOD.c
* | Author : Waveshare team
* | Function : Drive GPIO
* | Info : Read and write gpio
*----------------
* | This version: V1.0
* | Date : 2023-11-15
* | Info : Basic version
*
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# GPIOD_IN the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the folGPIOD_LOWing conditions:
#
# The above copyright notice and this permission notice shall be included GPIOD_IN
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. GPIOD_IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER GPIOD_IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# GPIOD_OUT OF OR GPIOD_IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS GPIOD_IN
# THE SOFTWARE.
#
******************************************************************************/
#include "RPI_gpiod.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gpiod.h>
struct gpiod_chip *gpiochip;
struct gpiod_line *gpioline;
int ret;
int GPIOD_Export()
{
char buffer[NUM_MAXBUF];
FILE *fp;
fp = popen("cat /proc/cpuinfo | grep 'Raspberry Pi 5'", "r");
if (fp == NULL) {
GPIOD_Debug("It is not possible to determine the model of the Raspberry PI\n");
return -1;
}
if(fgets(buffer, sizeof(buffer), fp) != NULL)
{
gpiochip = gpiod_chip_open("/dev/gpiochip4");
if (gpiochip == NULL)
{
GPIOD_Debug( "gpiochip4 Export Failed\n");
return -1;
}
}
else
{
gpiochip = gpiod_chip_open("/dev/gpiochip0");
if (gpiochip == NULL)
{
GPIOD_Debug( "gpiochip0 Export Failed\n");
return -1;
}
}
return 0;
}
int GPIOD_Unexport(int Pin)
{
gpioline = gpiod_chip_get_line(gpiochip, Pin);
if (gpioline == NULL)
{
GPIOD_Debug( "Export Failed: Pin%d\n", Pin);
return -1;
}
gpiod_line_release(gpioline);
GPIOD_Debug( "Unexport: Pin%d\r\n", Pin);
return 0;
}
int GPIOD_Unexport_GPIO(void)
{
gpiod_line_release(gpioline);
gpiod_chip_close(gpiochip);
return 0;
}
int GPIOD_Direction(int Pin, int Dir)
{
gpioline = gpiod_chip_get_line(gpiochip, Pin);
if (gpioline == NULL)
{
GPIOD_Debug( "Export Failed: Pin%d\n", Pin);
return -1;
}
if(Dir == GPIOD_IN)
{
ret = gpiod_line_request_input(gpioline, "gpio");
if (ret != 0)
{
GPIOD_Debug( "Export Failed: Pin%d\n", Pin);
return -1;
}
GPIOD_Debug("Pin%d:intput\r\n", Pin);
}
else
{
ret = gpiod_line_request_output(gpioline, "gpio", 0);
if (ret != 0)
{
GPIOD_Debug( "Export Failed: Pin%d\n", Pin);
return -1;
}
GPIOD_Debug("Pin%d:Output\r\n", Pin);
}
return 0;
}
int GPIOD_Read(int Pin)
{
gpioline = gpiod_chip_get_line(gpiochip, Pin);
if (gpioline == NULL)
{
GPIOD_Debug( "Export Failed: Pin%d\n", Pin);
return -1;
}
ret = gpiod_line_get_value(gpioline);
if (ret < 0)
{
GPIOD_Debug( "failed to read value!\n");
return -1;
}
return(ret);
}
int GPIOD_Write(int Pin, int value)
{
gpioline = gpiod_chip_get_line(gpiochip, Pin);
if (gpioline == NULL)
{
GPIOD_Debug( "Export Failed: Pin%d\n", Pin);
return -1;
}
ret = gpiod_line_set_value(gpioline, value);
if (ret != 0)
{
GPIOD_Debug( "failed to write value! : Pin%d\n", Pin);
return -1;
}
return 0;
}
@@ -0,0 +1,88 @@
/*****************************************************************************
* | File : gpiod.h
* | Author : Waveshare team
* | Function : Drive GPIO
* | Info : Read and write gpio
*----------------
* | This version: V1.0
* | Date : 2023-11-15
* | Info : Basic version
*d
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#D
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
************************D******************************************************/
#ifndef __GPIOD_
#define __GPIOD_
#include <stdio.h>
#include <gpiod.h>
#define GPIOD_IN 0
#define GPIOD_OUT 1
#define GPIOD_LOW 0
#define GPIOD_HIGH 1
#define NUM_MAXBUF 4
#define DIR_MAXSIZ 60
#define GPIOD_DEBUG 0
#if GPIOD_DEBUG
#define GPIOD_Debug(__info,...) printf("Debug: " __info,##__VA_ARGS__)
#else
#define GPIOD_Debug(__info,...)
#endif
// BCM GPIO for Jetson nano
#define GPIO4 4 // 7, 4
#define GPIO17 7 // 11, 17
#define GPIO18 18 // 12, 18
#define GPIO27 27 // 13, 27
#define GPIO22 22 // 15, 22
#define GPIO23 23 // 16, 23
#define GPIO24 24 // 18, 24
#define SPI0_MOSI 10 // 19, 10
#define SPI0_MISO 9 // 21, 9
#define GPIO25 28 // 22, 25
#define SPI0_SCK 11 // 23, 11
#define SPI0_CS0 8 // 24, 8
#define SPI0_CS1 7 // 26, 7
#define GPIO5 5 // 29, 5
#define GPIO6 6 // 31, 6
#define GPIO12 12 // 32, 12
#define GPIO13 13 // 33, 13
#define GPIO19 19 // 35, 19
#define GPIO16 16 // 36, 16
#define GPIO26 26 // 37, 26
#define GPIO20 20 // 38, 20
#define GPIO21 21 // 40, 21
extern struct gpiod_chip *gpiochip;
extern struct gpiod_line *gpioline;
extern int ret;
int GPIOD_Export();
int GPIOD_Unexport(int Pin);
int GPIOD_Unexport_GPIO(void);
int GPIOD_Direction(int Pin, int Dir);
int GPIOD_Read(int Pin);
int GPIOD_Write(int Pin, int value);
#endif
@@ -0,0 +1,363 @@
/*****************************************************************************
* | File : dev_hardware_SPI.c
* | Author : Waveshare team
* | Function : Read and write /dev/SPI, hardware SPI
* | Info :
*----------------
* | This version: V1.0
* | Date : 2019-06-26
* | Info : Basic version
*
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "dev_hardware_SPI.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
HARDWARE_SPI hardware_SPI;
static uint8_t bits = 8;
#define SPI_CS_HIGH 0x04 //Chip select high
#define SPI_LSB_FIRST 0x08 //LSB
#define SPI_3WIRE 0x10 //3-wire mode SI and SO same line
#define SPI_LOOP 0x20 //Loopback mode
#define SPI_NO_CS 0x40 //A single device occupies one SPI bus, so there is no chip select
#define SPI_READY 0x80 //Slave pull low to stop data transmission
struct spi_ioc_transfer tr;
/******************************************************************************
function: SPI port initialization
parameter:
SPI_device : Device name
Info:
/dev/spidev0.0
/dev/spidev0.1
******************************************************************************/
void DEV_HARDWARE_SPI_begin(char *SPI_device)
{
//device
int ret = 0;
if((hardware_SPI.fd = open(SPI_device, O_RDWR )) < 0) {
perror("Failed to open SPI device.\n");
DEV_HARDWARE_SPI_Debug("Failed to open SPI device\r\n");
exit(1);
} else {
DEV_HARDWARE_SPI_Debug("open : %s\r\n", SPI_device);
}
hardware_SPI.mode = 0;
ret = ioctl(hardware_SPI.fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1) {
DEV_HARDWARE_SPI_Debug("can't set bits per word\r\n");
}
ret = ioctl(hardware_SPI.fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1) {
DEV_HARDWARE_SPI_Debug("can't get bits per word\r\n");
}
tr.bits_per_word = bits;
DEV_HARDWARE_SPI_Mode(SPI_MODE_0);
DEV_HARDWARE_SPI_ChipSelect(SPI_CS_Mode_LOW);
DEV_HARDWARE_SPI_SetBitOrder(SPI_BIT_ORDER_LSBFIRST);
DEV_HARDWARE_SPI_setSpeed(20000000);
DEV_HARDWARE_SPI_SetDataInterval(0);
}
void DEV_HARDWARE_SPI_beginSet(char *SPI_device, SPIMode mode, uint32_t speed)
{
//device
int ret = 0;
hardware_SPI.mode = 0;
if((hardware_SPI.fd = open(SPI_device, O_RDWR )) < 0) {
perror("Failed to open SPI device.\n");
exit(1);
} else {
DEV_HARDWARE_SPI_Debug("open : %s\r\n", SPI_device);
}
ret = ioctl(hardware_SPI.fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
DEV_HARDWARE_SPI_Debug("can't set bits per word\r\n");
ret = ioctl(hardware_SPI.fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
DEV_HARDWARE_SPI_Debug("can't get bits per word\r\n");
DEV_HARDWARE_SPI_Mode(mode);
DEV_HARDWARE_SPI_ChipSelect(SPI_CS_Mode_LOW);
DEV_HARDWARE_SPI_setSpeed(speed);
DEV_HARDWARE_SPI_SetDataInterval(0);
}
/******************************************************************************
function: SPI device End
parameter:
Info:
******************************************************************************/
void DEV_HARDWARE_SPI_end(void)
{
hardware_SPI.mode = 0;
if (close(hardware_SPI.fd) != 0){
DEV_HARDWARE_SPI_Debug("Failed to close SPI device\r\n");
perror("Failed to close SPI device.\n");
}
}
/******************************************************************************
function: Set SPI speed
parameter:
Info: Return 1 success
Return -1 failed
******************************************************************************/
int DEV_HARDWARE_SPI_setSpeed(uint32_t speed)
{
uint32_t speed1 = hardware_SPI.speed;
hardware_SPI.speed = speed;
//Write speed
if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
DEV_HARDWARE_SPI_Debug("can't set max speed hz\r\n");
hardware_SPI.speed = speed1;//Setting failure rate unchanged
return -1;
}
//Read the speed of just writing
if (ioctl(hardware_SPI.fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) {
DEV_HARDWARE_SPI_Debug("can't get max speed hz\r\n");
hardware_SPI.speed = speed1;//Setting failure rate unchanged
return -1;
}
hardware_SPI.speed = speed;
tr.speed_hz = hardware_SPI.speed;
return 1;
}
/******************************************************************************
function: Set SPI Mode
parameter:
Info:
SPIMode:
SPI_MODE0
SPI_MODE1
SPI_MODE2
SPI_MODE3
Return :
Return 1 success
Return -1 failed
******************************************************************************/
int DEV_HARDWARE_SPI_Mode(SPIMode mode)
{
hardware_SPI.mode &= 0xfC;//Clear low 2 digits
hardware_SPI.mode |= mode;//Setting mode
//Write device
if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
DEV_HARDWARE_SPI_Debug("can't set spi mode\r\n");
return -1;
}
return 1;
}
/******************************************************************************
function: Set SPI CS Enable
parameter:
Info:
EN:
DISABLE
ENABLE
Return :
Return 1 success
Return -1 failed
******************************************************************************/
int DEV_HARDWARE_SPI_CSEN(SPICSEN EN)
{
if(EN == ENABLE){
hardware_SPI.mode |= SPI_NO_CS;
}else {
hardware_SPI.mode &= ~SPI_NO_CS;
}
//Write device
if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
DEV_HARDWARE_SPI_Debug("can't set spi CS EN\r\n");
return -1;
}
return 1;
}
/******************************************************************************
function: Chip Select
parameter:
Info:
CS_Mode:
SPI_CS_Mode_LOW
SPI_CS_Mode_HIGH
SPI_CS_Mode_NONE
Return :
Return 1 success
Return -1 failed
******************************************************************************/
int DEV_HARDWARE_SPI_ChipSelect(SPIChipSelect CS_Mode)
{
if(CS_Mode == SPI_CS_Mode_HIGH){
hardware_SPI.mode |= SPI_CS_HIGH;
hardware_SPI.mode &= ~SPI_NO_CS;
DEV_HARDWARE_SPI_Debug("CS HIGH \r\n");
}else if(CS_Mode == SPI_CS_Mode_LOW){
hardware_SPI.mode &= ~SPI_CS_HIGH;
hardware_SPI.mode &= ~SPI_NO_CS;
}else if(CS_Mode == SPI_CS_Mode_NONE){
hardware_SPI.mode |= SPI_NO_CS;
}
if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
DEV_HARDWARE_SPI_Debug("can't set spi mode\r\n");
return -1;
}
return 1;
}
/******************************************************************************
function: Sets the SPI bit order
parameter:
Info:
Order:
SPI_BIT_ORDER_LSBFIRST
SPI_BIT_ORDER_MSBFIRST
Return :
Return 1 success
Return -1 failed
******************************************************************************/
int DEV_HARDWARE_SPI_SetBitOrder(SPIBitOrder Order)
{
if(Order == SPI_BIT_ORDER_LSBFIRST){
hardware_SPI.mode |= SPI_LSB_FIRST;
DEV_HARDWARE_SPI_Debug("SPI_LSB_FIRST\r\n");
}else if(Order == SPI_BIT_ORDER_MSBFIRST){
hardware_SPI.mode &= ~SPI_LSB_FIRST;
DEV_HARDWARE_SPI_Debug("SPI_MSB_FIRST\r\n");
}
// DEV_HARDWARE_SPI_Debug("hardware_SPI.mode = 0x%02x\r\n", hardware_SPI.mode);
int fd = ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode);
DEV_HARDWARE_SPI_Debug("fd = %d\r\n",fd);
if (fd == -1) {
DEV_HARDWARE_SPI_Debug("can't set spi SPI_LSB_FIRST\r\n");
return -1;
}
return 1;
}
/******************************************************************************
function: Sets the SPI Bus Mode
parameter:
Info:
Order:
SPI_3WIRE_Mode
SPI_4WIRE_Mode
Return :
Return 1 success
Return -1 failed
******************************************************************************/
int DEV_HARDWARE_SPI_SetBusMode(BusMode mode)
{
if(mode == SPI_3WIRE_Mode){
hardware_SPI.mode |= SPI_3WIRE;
}else if(mode == SPI_4WIRE_Mode){
hardware_SPI.mode &= ~SPI_3WIRE;
}
if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
DEV_HARDWARE_SPI_Debug("can't set spi mode\r\n");
return -1;
}
return 1;
}
/******************************************************************************
function:
Time interval after transmission of one byte during continuous transmission
parameter:
us : Interval time (us)
Info:
******************************************************************************/
void DEV_HARDWARE_SPI_SetDataInterval(uint16_t us)
{
hardware_SPI.delay = us;
tr.delay_usecs = hardware_SPI.delay;
}
/******************************************************************************
function: SPI port sends one byte of data
parameter:
buf : Sent data
Info:
******************************************************************************/
uint8_t DEV_HARDWARE_SPI_TransferByte(uint8_t buf)
{
uint8_t rbuf[1];
tr.len = 1;
tr.tx_buf = (unsigned long)&buf;
tr.rx_buf = (unsigned long)rbuf;
//ioctl Operation, transmission of data
if ( ioctl(hardware_SPI.fd, SPI_IOC_MESSAGE(1), &tr) < 1 )
DEV_HARDWARE_SPI_Debug("can't send spi message\r\n");
return rbuf[0];
}
/******************************************************************************
function: The SPI port reads a byte
parameter:
Info: Return read data
******************************************************************************/
int DEV_HARDWARE_SPI_Transfer(uint8_t *buf, uint32_t len)
{
uint8_t rbuf[len];
tr.len = len;
tr.tx_buf = (unsigned long)buf;
tr.rx_buf = (unsigned long)rbuf;
//ioctl Operation, transmission of data
if (ioctl(hardware_SPI.fd, SPI_IOC_MESSAGE(1), &tr) < 1 ){
DEV_HARDWARE_SPI_Debug("can't send spi message\r\n");
return -1;
}
return 1;
}
@@ -0,0 +1,120 @@
/*****************************************************************************
* | File : dev_hardware_SPI.h
* | Author : Waveshare team
* | Function : Read and write /dev/SPI, hardware SPI
* | Info :
*----------------
* | This version: V1.0
* | Date : 2019-06-26
* | Info : Basic version
*
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#ifndef __DEV_HARDWARE_SPI_
#define __DEV_HARDWARE_SPI_
#include <stdint.h>
#define DEV_HARDWARE_SPI_DEBUG 0
#if DEV_HARDWARE_SPI_DEBUG
#define DEV_HARDWARE_SPI_Debug(__info,...) printf("Debug: " __info,##__VA_ARGS__)
#else
#define DEV_HARDWARE_SPI_Debug(__info,...)
#endif
#define SPI_CPHA 0x01
#define SPI_CPOL 0x02
#define SPI_MODE_0 (0|0)
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
typedef enum{
SPI_MODE0 = SPI_MODE_0, /*!< CPOL = 0, CPHA = 0 */
SPI_MODE1 = SPI_MODE_1, /*!< CPOL = 0, CPHA = 1 */
SPI_MODE2 = SPI_MODE_2, /*!< CPOL = 1, CPHA = 0 */
SPI_MODE3 = SPI_MODE_3 /*!< CPOL = 1, CPHA = 1 */
}SPIMode;
typedef enum{
DISABLE = 0,
ENABLE = 1
}SPICSEN;
typedef enum{
SPI_CS_Mode_LOW = 0, /*!< Chip Select 0 */
SPI_CS_Mode_HIGH = 1, /*!< Chip Select 1 */
SPI_CS_Mode_NONE = 3 /*!< No CS, control it yourself */
}SPIChipSelect;
typedef enum
{
SPI_BIT_ORDER_LSBFIRST = 0, /*!< LSB First */
SPI_BIT_ORDER_MSBFIRST = 1 /*!< MSB First */
}SPIBitOrder;
typedef enum
{
SPI_3WIRE_Mode = 0,
SPI_4WIRE_Mode = 1
}BusMode;
/**
* Define SPI attribute
**/
typedef struct SPIStruct {
//GPIO
uint16_t SCLK_PIN;
uint16_t MOSI_PIN;
uint16_t MISO_PIN;
uint16_t CS0_PIN;
uint16_t CS1_PIN;
uint32_t speed;
uint16_t mode;
uint16_t delay;
int fd; //
} HARDWARE_SPI;
void DEV_HARDWARE_SPI_begin(char *SPI_device);
void DEV_HARDWARE_SPI_beginSet(char *SPI_device, SPIMode mode, uint32_t speed);
void DEV_HARDWARE_SPI_end(void);
int DEV_HARDWARE_SPI_setSpeed(uint32_t speed);
uint8_t DEV_HARDWARE_SPI_TransferByte(uint8_t buf);
int DEV_HARDWARE_SPI_Transfer(uint8_t *buf, uint32_t len);
void DEV_HARDWARE_SPI_SetDataInterval(uint16_t us);
int DEV_HARDWARE_SPI_SetBusMode(BusMode mode);
int DEV_HARDWARE_SPI_SetBitOrder(SPIBitOrder Order);
int DEV_HARDWARE_SPI_ChipSelect(SPIChipSelect CS_Mode);
int DEV_HARDWARE_SPI_CSEN(SPICSEN EN);
int DEV_HARDWARE_SPI_Mode(SPIMode mode);
#endif
@@ -0,0 +1,112 @@
/*****************************************************************************
* | File : dev_hardware_i2c.c
* | Author : Waveshare team
* | Function : Read and write /dev/i2C, hardware I2C
* | Info :
*----------------
* | This version: V1.0
* | Date : 2019-06-26
* | Info : Basic version
*
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "dev_hardware_i2c.h"
#include <stdio.h>
#include <stdlib.h> //exit()
#include <fcntl.h> //define O_RDWR
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
HARDWARE_I2C hardware_i2c;
/******************************************************************************
function: I2C device initialization
parameter:
i2c_device : Device name
Info: /dev/i2c-*
******************************************************************************/
void DEV_HARDWARE_I2C_begin(char *i2c_device)
{
//device
if((hardware_i2c.fd = open(i2c_device, O_RDWR)) < 0) { //open I2C
perror("Failed to open i2c device.\n");
printf("Failed to open i2c device\r\n");
exit(1);
} else {
DEV_HARDWARE_I2C_Debug("open : %s\r\n", i2c_device);
}
}
/******************************************************************************
function: I2C device End
parameter:
Info:
******************************************************************************/
void DEV_HARDWARE_I2C_end(void)
{
if (close(hardware_i2c.fd) != 0){
perror("Failed to close i2c device.\n");
}
}
/******************************************************************************
function: Set the device address for I2C access
parameter:
addr : Device address accessed by I2C
Info:
******************************************************************************/
void DEV_HARDWARE_I2C_setSlaveAddress(uint8_t addr)
{
if(ioctl(hardware_i2c.fd, I2C_SLAVE, addr) < 0) {
printf("Failed to access bus.\n");
exit(1);
}
}
/******************************************************************************
function: I2C Send data
parameter:
buf : Send data buffer address
len : Send data length
Info:
******************************************************************************/
uint8_t DEV_HARDWARE_I2C_write(const char * buf, uint32_t len)
{
write(hardware_i2c.fd, buf, len);
return 0;
}
/******************************************************************************
function: I2C read data
parameter:
buf : Sead data buffer address
len : Sead data length
Info:
******************************************************************************/
uint8_t DEV_HARDWARE_I2C_read(char* buf, uint32_t len)
{
read(hardware_i2c.fd, buf, len);
return 0;
}
@@ -0,0 +1,61 @@
/*****************************************************************************
* | File : dev_hardware_i2c.h
* | Author : Waveshare team
* | Function : Read and write /dev/i2C, hardware I2C
* | Info :
*----------------
* | This version: V1.0
* | Date : 2019-06-26
* | Info : Basic version
*
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#ifndef __DEV_HARDWARE_I2C_
#define __DEV_HARDWARE_I2C_
#include <stdint.h>
#define DEV_HARDWARE_I2C_DEBUG 0
#if DEV_HARDWARE_I2C_DEBUG
#define DEV_HARDWARE_I2C_Debug(__info,...) printf("Debug: " __info,##__VA_ARGS__)
#else
#define DEV_HARDWARE_I2C_Debug(__info,...)
#endif
/**
* Define I2C attribute
**/
typedef struct I2CStruct {
//GPIO
uint16_t SCL_PIN;
uint16_t SDA_PIN;
int fd; //I2C device file descriptor
uint16_t addr; //I2C device address
} HARDWARE_I2C;
void DEV_HARDWARE_I2C_begin(char *i2c_device);
void DEV_HARDWARE_I2C_end(void);
void DEV_HARDWARE_I2C_setSlaveAddress(uint8_t addr);
uint8_t DEV_HARDWARE_I2C_write(const char * buf, uint32_t len);
uint8_t DEV_HARDWARE_I2C_read(char* buf, uint32_t len);
#endif