From 03ada50f4e3993fc9e3d4c17e952f12bb67d7d98 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Tue, 27 Aug 2019 00:50:13 +0800
Subject: [PATCH] add AT91 GPIO AND spi library
---
program/lylib/at91_sysGpio.c | 210 +++++++++++++++
program/lylib/at91_sysGpioDef.h | 221 +++++++++++++++
program/lylib/spidev.c | 255 ++++++++++++++++++
program/lylib/at91_sysGpio.h | 62 ++++
program/lylib/spidev.h | 75 +++++
5 files changed, 823 insertions(+), 0 deletions(-)
diff --git a/program/lylib/at91_sysGpio.c b/program/lylib/at91_sysGpio.c
new file mode 100644
index 0000000..add9038
--- /dev/null
+++ b/program/lylib/at91_sysGpio.c
@@ -0,0 +1,210 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: at91_sysGpio.c
+ * Description: This file si GPIO API operatore on /sys/class/gpio/xxx
+ *
+ * Version: 1.0.0(2019年08月26日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年08月26日 22时28分19秒"
+ *
+ ********************************************************************************/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "at91_sysGpio.h"
+
+
+/* export $port in /sys/class/gpio/export */
+int gpio_export(const char *port)
+{
+ char fpath[SYSFILE_LEN];
+ FILE *fp;
+ int pin;
+
+ if(!port)
+ {
+ gpio_print("invalid input arguments\n");
+ return -1;
+ }
+
+ snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
+
+ /* GPIO port already export */
+ if( !access(fpath, F_OK) )
+ {
+ gpio_print("%s already export\n", port);
+ return 0;
+ }
+
+ if( !(fp=fopen(SYSGPIO_EXPORT_PATH, "w")) )
+ {
+ gpio_print("open '%s' failure: %s\n", SYSGPIO_EXPORT_PATH, strerror(errno));
+ return -2;
+ }
+
+ pin = at91_port2pin(port);
+ fprintf(fp, "%d", pin);
+
+ fclose(fp);
+
+ return 0;
+}
+
+
+/* unexport $port in /sys/class/gpio/unexport */
+int gpio_unexport(const char *port)
+{
+ char fpath[SYSFILE_LEN];
+ FILE *fp;
+ int pin;
+
+ if(!port)
+ {
+ gpio_print("invalid input arguments\n");
+ return -1;
+ }
+
+ snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
+
+ /* GPIO port not export */
+ if( access(fpath, F_OK) )
+ {
+ gpio_print("%s not export\n", port);
+ return 0;
+ }
+
+ if( !(fp=fopen(SYSGPIO_UNEXPORT_PATH, "w")) )
+ {
+ gpio_print("open '%s' failure: %s\n", SYSGPIO_EXPORT_PATH, strerror(errno));
+ return -2;
+ }
+
+ pin = at91_port2pin(port);
+ fprintf(fp, "%d", pin);
+
+ fclose(fp);
+
+ return 0;
+}
+
+
+/* configure $port direction as $mode */
+int gpio_config(const char *port, const char *mode)
+{
+ char fpath[SYSFILE_LEN];
+ FILE *fp;
+ int size;
+
+ if(!port)
+ {
+ gpio_print("invalid input arguments\n");
+ return 0;
+ }
+
+ snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
+
+ if( access(fpath, F_OK) ) /* GPIO port not export */
+ {
+ if( gpio_export(port) < 0 )
+ return -1;
+ }
+
+ size = SYSFILE_LEN-strlen(fpath);
+ strncat(fpath, "/direction", size);
+ if( !(fp=fopen(fpath, "w")) )
+ {
+ gpio_print("open '%s' failure: %s\n", fpath, strerror(errno));
+ return -1;
+ }
+
+ fputs(mode, fp);
+
+ fclose(fp);
+
+ return 0;
+}
+
+
+
+/* write $value into GPIO $port */
+int gpio_write(const char *port, const char *value)
+{
+ char fpath[SYSFILE_LEN];
+ FILE *fp;
+ int size;
+
+ if(!port)
+ {
+ gpio_print("invalid input arguments\n");
+ return 0;
+ }
+
+ snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
+
+ if( access(fpath, F_OK) ) /* GPIO port not export */
+ {
+ if( gpio_export(port) < 0 )
+ return -1;
+ }
+
+ size = SYSFILE_LEN-strlen(fpath);
+ strncat(fpath, "/value", size);
+ if( !(fp=fopen(fpath, "w")) )
+ {
+ gpio_print("open '%s' failure: %s\n", fpath, strerror(errno));
+ return -1;
+ }
+
+ fputs(value, fp);
+
+ fclose(fp);
+
+ return 0;
+}
+
+
+/* read gpio value from $port */
+int gpio_read(const char *port)
+{
+ char fpath[SYSFILE_LEN];
+ FILE *fp;
+ int size;
+ char v_str[32];
+
+ if(!port)
+ {
+ gpio_print("invalid input arguments\n");
+ return 0;
+ }
+
+ snprintf(fpath, SYSFILE_LEN, "%s/%s", SYSGPIO_PATH, port);
+
+ if( access(fpath, F_OK) ) /* GPIO port not export */
+ {
+ return -1;
+ }
+
+ size = SYSFILE_LEN-strlen(fpath);
+ strncat(fpath, "/value", size);
+ if( !(fp=fopen(fpath, "r")) )
+ {
+ gpio_print("open '%s' failure: %s\n", fpath, strerror(errno));
+ return -1;
+ }
+
+ memset(v_str, 0, sizeof(v_str));
+ fgets(v_str, sizeof(v_str), fp);
+
+ fclose(fp);
+
+ return atoi(v_str);
+}
+
diff --git a/program/lylib/at91_sysGpio.h b/program/lylib/at91_sysGpio.h
new file mode 100644
index 0000000..556750f
--- /dev/null
+++ b/program/lylib/at91_sysGpio.h
@@ -0,0 +1,62 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: at91_sysGpio.h
+ * Description: This file si GPIO API operatore on /sys/class/gpio/xxx
+ *
+ * Version: 1.0.0(2019年08月26日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年08月26日 22时28分19秒"
+ *
+ ********************************************************************************/
+
+#ifndef _AT91_SYSGPIO_H_
+#define _AT91_SYSGPIO_H_
+
+#include "at91_sysGpioDef.h"
+
+#define SYSFILE_LEN 64
+
+#define SYSGPIO_PATH "/sys/class/gpio/"
+
+#define SYSGPIO_EXPORT_PATH SYSGPIO_PATH"export"
+#define SYSGPIO_UNEXPORT_PATH SYSGPIO_PATH"unexport"
+
+//#define GPIO_DEBUG_PRINT
+
+#ifdef GPIO_DEBUG_PRINT
+#define gpio_print(format,args...) printf(format, ##args)
+#else
+#define gpio_print(format,args...) do{} while(0);
+#endif
+
+
+/* export $port in /sys/class/gpio/export */
+extern int gpio_export(const char *port);
+
+
+/* unexport $port in /sys/class/gpio/unexport */
+extern int gpio_unexport(const char *port);
+
+
+#define M_IN "in" /* set GPIO as input mode */
+#define M_OUT "out" /* set GPIO as output mode */
+#define M_HIGH "high" /* set GPIO as output mode and value be high<1> */
+#define M_LOW "low" /* set GPIO as output mode and value be low<0> */
+/* configure $port direction as $mode */
+extern int gpio_config(const char *port, const char *mode);
+
+
+#define V_HIGH "1"
+#define V_LOW "0"
+/* write $value into GPIO $port */
+extern int gpio_write(const char *port, const char *value);
+
+
+/* read gpio value from $port */
+extern int gpio_read(const char *port);
+
+#endif /* ----- #ifndef _AT91_SYSGPIO_H_ ----- */
+
+
diff --git a/program/lylib/at91_sysGpioDef.h b/program/lylib/at91_sysGpioDef.h
new file mode 100644
index 0000000..a4f827d
--- /dev/null
+++ b/program/lylib/at91_sysGpioDef.h
@@ -0,0 +1,221 @@
+/********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: at91_sysGpioDef.h
+ * Description: This head file
+ *
+ * Version: 1.0.0(2019年08月26日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年08月26日 21时46分02秒"
+ *
+ ********************************************************************************/
+
+#ifndef _AT91_SYSGPIODEF_H_
+#define _AT91_SYSGPIODEF_H_
+
+#include <ctype.h>
+#include <stdlib.h>
+
+#define PA(x) "pioA"#x
+#define PB(x) "pioB"#x
+#define PC(x) "pioC"#x
+#define PD(x) "pioD"#x
+#define PE(x) "pioE"#x
+
+/* SAMA5D44 devided all GPIOs into 5 groups(PA,PB,PC,PD,PE), and each group control 32 Pins
+ *
+ * This macro used convert PAx,PBx...,PEx to Pin number: 0~158
+ * s should be: PA0-PA31, PB0-PB31, PC0-PC31, PD0-PD31, PE0-PE30(158)
+ */
+#define at91_port2pin(p) ((tolower(p[3])-'a')*32 + atoi(p+4) )
+
+
+/*+-----------------------------------------------------+
+ *| GPIO PortA: PA0~PA31 defined as "pioA0"-"pioA31" |
+ *+-----------------------------------------------------+*/
+
+#define PA0 PA(0)
+#define PA1 PA(1)
+#define PA2 PA(2)
+#define PA3 PA(3)
+#define PA4 PA(4)
+#define PA5 PA(5)
+#define PA6 PA(6)
+#define PA7 PA(7)
+#define PA8 PA(8)
+#define PA9 PA(9)
+#define PA10 PA(10)
+#define PA11 PA(11)
+#define PA12 PA(12)
+#define PA13 PA(13)
+#define PA14 PA(14)
+#define PA15 PA(15)
+#define PA16 PA(16)
+#define PA17 PA(17)
+#define PA18 PA(18)
+#define PA19 PA(19)
+#define PA20 PA(20)
+#define PA21 PA(21)
+#define PA22 PA(22)
+#define PA23 PA(23)
+#define PA24 PA(24)
+#define PA25 PA(25)
+#define PA26 PA(26)
+#define PA27 PA(27)
+#define PA28 PA(28)
+#define PA29 PA(29)
+#define PA30 PA(30)
+#define PA31 PA(31)
+
+
+/*+-----------------------------------------------------+
+ *| GPIO PortB: PB0~PB31 defined as "pioB0"-"pioB31" |
+ *+-----------------------------------------------------+*/
+
+#define PB0 PB(0)
+#define PB1 PB(1)
+#define PB2 PB(2)
+#define PB3 PB(3)
+#define PB4 PB(4)
+#define PB5 PB(5)
+#define PB6 PB(6)
+#define PB7 PB(7)
+#define PB8 PB(8)
+#define PB9 PB(9)
+#define PB10 PB(10)
+#define PB11 PB(11)
+#define PB12 PB(12)
+#define PB13 PB(13)
+#define PB14 PB(14)
+#define PB15 PB(15)
+#define PB16 PB(16)
+#define PB17 PB(17)
+#define PB18 PB(18)
+#define PB19 PB(19)
+#define PB20 PB(20)
+#define PB21 PB(21)
+#define PB22 PB(22)
+#define PB23 PB(23)
+#define PB24 PB(24)
+#define PB25 PB(25)
+#define PB26 PB(26)
+#define PB27 PB(27)
+#define PB28 PB(28)
+#define PB29 PB(29)
+#define PB30 PB(30)
+#define PB31 PB(31)
+
+/*+-----------------------------------------------------+
+ *| GPIO PortC: PC0~PC31 defined as "pioC0"-"pioC31" |
+ *+-----------------------------------------------------+*/
+
+#define PC0 PC(0)
+#define PC1 PC(1)
+#define PC2 PC(2)
+#define PC3 PC(3)
+#define PC4 PC(4)
+#define PC5 PC(5)
+#define PC6 PC(6)
+#define PC7 PC(7)
+#define PC8 PC(8)
+#define PC9 PC(9)
+#define PC10 PC(10)
+#define PC11 PC(11)
+#define PC12 PC(12)
+#define PC13 PC(13)
+#define PC14 PC(14)
+#define PC15 PC(15)
+#define PC16 PC(16)
+#define PC17 PC(17)
+#define PC18 PC(18)
+#define PC19 PC(19)
+#define PC20 PC(20)
+#define PC21 PC(21)
+#define PC22 PC(22)
+#define PC23 PC(23)
+#define PC24 PC(24)
+#define PC25 PC(25)
+#define PC26 PC(26)
+#define PC27 PC(27)
+#define PC28 PC(28)
+#define PC29 PC(29)
+#define PC30 PC(30)
+#define PC31 PC(31)
+
+/*+-----------------------------------------------------+
+ *| GPIO PortD: PD0~PD31 defined as "pioD0"-"pioD31" |
+ *+-----------------------------------------------------+*/
+
+#define PD0 PD(0)
+#define PD1 PD(1)
+#define PD2 PD(2)
+#define PD3 PD(3)
+#define PD4 PD(4)
+#define PD5 PD(5)
+#define PD6 PD(6)
+#define PD7 PD(7)
+#define PD8 PD(8)
+#define PD9 PD(9)
+#define PD10 PD(10)
+#define PD11 PD(11)
+#define PD12 PD(12)
+#define PD13 PD(13)
+#define PD14 PD(14)
+#define PD15 PD(15)
+#define PD16 PD(16)
+#define PD17 PD(17)
+#define PD18 PD(18)
+#define PD19 PD(19)
+#define PD20 PD(20)
+#define PD21 PD(21)
+#define PD22 PD(22)
+#define PD23 PD(23)
+#define PD24 PD(24)
+#define PD25 PD(25)
+#define PD26 PD(26)
+#define PD27 PD(27)
+#define PD28 PD(28)
+#define PD29 PD(29)
+#define PD30 PD(30)
+#define PD31 PD(31)
+
+/*+-----------------------------------------------------+
+ *| GPIO PortE: PE0~PE30 defined as "pioE0"-"pioE30" |
+ *+-----------------------------------------------------+*/
+
+#define PE0 PE(0)
+#define PE1 PE(1)
+#define PE2 PE(2)
+#define PE3 PE(3)
+#define PE4 PE(4)
+#define PE5 PE(5)
+#define PE6 PE(6)
+#define PE7 PE(7)
+#define PE8 PE(8)
+#define PE9 PE(9)
+#define PE10 PE(10)
+#define PE11 PE(11)
+#define PE12 PE(12)
+#define PE13 PE(13)
+#define PE14 PE(14)
+#define PE15 PE(15)
+#define PE16 PE(16)
+#define PE17 PE(17)
+#define PE18 PE(18)
+#define PE19 PE(19)
+#define PE20 PE(20)
+#define PE21 PE(21)
+#define PE22 PE(22)
+#define PE23 PE(23)
+#define PE24 PE(24)
+#define PE25 PE(25)
+#define PE26 PE(26)
+#define PE27 PE(27)
+#define PE28 PE(28)
+#define PE29 PE(29)
+#define PE30 PE(30)
+
+
+#endif /* ----- #ifndef _AT91_SYSGPIODEF_H_ ----- */
+
diff --git a/program/lylib/spidev.c b/program/lylib/spidev.c
new file mode 100644
index 0000000..8a5d29a
--- /dev/null
+++ b/program/lylib/spidev.c
@@ -0,0 +1,255 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: spidev.c
+ * Description: This file is spidev user space API.
+ *
+ * Version: 1.0.0(2019年08月19日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年08月19日 23时18分54秒"
+ *
+ ********************************************************************************/
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "spidev.h"
+
+int spi_init(spidev_t *spi, char *spidev, uint8_t bpw, uint32_t speed, uint32_t delay, uint32_t mode)
+{
+ int rv = 0;
+
+ if( !spi || !spidev )
+ {
+ spi_dbg("Invalid input arguments\n");
+ return -1;
+ }
+
+ memset(spi, 0, sizeof(*spi));
+
+ strncpy(spi->devname, spidev, DEVNAME_LEN);
+ spi->bits = bpw;
+ spi->speed = speed*1000; /* speed unit is KHz */
+ spi->delay = delay;
+ spi->mode = mode;
+
+ spi->fd = open(spidev, O_RDWR);
+ if( spi->fd < 0)
+ {
+ spi_dbg("Open SPI device '%s' failure: %s\n", spidev, strerror(errno));
+ rv = -2;
+ goto cleanup;
+ }
+
+ /* set bits per word */
+ if( ioctl(spi->fd, SPI_IOC_WR_BITS_PER_WORD, &bpw) < 0 )
+ {
+ spi_dbg("Set SPI '%s' bit per words to [%d] failure: %s\n", spidev, bpw, strerror(errno));
+ rv = -3;
+ goto cleanup;
+ }
+
+ /* set bits per word */
+ if( ioctl(spi->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi->speed) < 0 )
+ {
+ spi_dbg("Set SPI '%s' speed to %dKHz failure: %s\n", spidev, speed, strerror(errno));
+ rv = -4;
+ goto cleanup;
+ }
+
+ /* set spi mode */
+ if( ioctl(spi->fd, SPI_IOC_WR_MODE32, &mode) < 0 )
+ {
+ spi_dbg("Set SPI '%s' mode to [0x%0x] failure: %s\n", spidev, mode, strerror(errno));
+ rv = -5;
+ goto cleanup;
+ }
+
+cleanup:
+ if( rv < 0 )
+ {
+ close(spi->fd);
+ }
+
+ return rv;
+}
+
+int spi_read(spidev_t *spi, char *buf, int size)
+{
+ int rv = 0;
+ void *dummy_buf;
+
+ struct spi_ioc_transfer tr =
+ {
+ .rx_buf = (unsigned long)buf,
+ .len = size,
+ .delay_usecs = spi->delay,
+ .speed_hz = spi->speed,
+ .bits_per_word = spi->bits,
+ };
+
+ if( !spi || !buf || size<=0 )
+ {
+ spi_dbg("Invalid input arguments\n");
+ return -1;
+ }
+
+ if( ! (dummy_buf=malloc(tr.len)) )
+ {
+ spi_dbg("spi_read malloc failure: %s\n", strerror(errno));
+ return -2;
+ }
+ tr.tx_buf = (unsigned long)dummy_buf;
+
+ if ( spi->mode & (SPI_TX_QUAD|SPI_RX_QUAD) )
+ tr.tx_nbits = 4;
+
+ if ( spi->mode & (SPI_TX_DUAL|SPI_RX_DUAL) )
+ tr.tx_nbits = 2;
+
+ if (!(spi->mode & SPI_LOOP))
+ {
+ if (spi->mode & (SPI_TX_QUAD|SPI_TX_DUAL))
+ tr.rx_buf = 0;
+ else if (spi->mode & (SPI_RX_QUAD|SPI_RX_DUAL))
+ tr.tx_buf = 0;
+ }
+
+ if( ioctl(spi->fd, SPI_IOC_MESSAGE(1), &tr) < 0)
+ {
+ spi_dbg("spi_read SPI_IOC_MESSAGE failure: %s\n", strerror(errno));
+ rv = -3;
+ goto cleanup;
+ }
+
+cleanup:
+ if( dummy_buf )
+ {
+ free( dummy_buf );
+ }
+
+ return rv;
+}
+
+
+int spi_write(spidev_t *spi, char *data, int nbytes)
+{
+ int rv = 0;
+ void *dummy_buf;
+
+ struct spi_ioc_transfer tr =
+ {
+ .tx_buf = (unsigned long)data,
+ .len = nbytes,
+ .delay_usecs = spi->delay,
+ .speed_hz = spi->speed,
+ .bits_per_word = spi->bits,
+ };
+
+
+ if( !spi || !data || nbytes<= 0)
+ {
+ spi_dbg("Invalid input arguments\n");
+ return -1;
+ }
+
+ if( ! (dummy_buf=malloc(tr.len)) )
+ {
+ spi_dbg("spi_read malloc failure: %s\n", strerror(errno));
+ return -1;
+ }
+ tr.rx_buf = (unsigned long)dummy_buf;
+
+ if ( spi->mode & (SPI_TX_QUAD|SPI_RX_QUAD) )
+ tr.tx_nbits = 4;
+
+ if ( spi->mode & (SPI_TX_DUAL|SPI_RX_DUAL) )
+ tr.tx_nbits = 2;
+
+ if (!(spi->mode & SPI_LOOP))
+ {
+ if (spi->mode & (SPI_TX_QUAD|SPI_TX_DUAL))
+ tr.rx_buf = 0;
+ else if (spi->mode & (SPI_RX_QUAD|SPI_RX_DUAL))
+ tr.tx_buf = 0;
+ }
+
+ if( ioctl(spi->fd, SPI_IOC_MESSAGE(1), &tr) < 0)
+ {
+ spi_dbg("spi_read SPI_IOC_MESSAGE failure: %s\n", strerror(errno));
+ rv = -2;
+ goto cleanup;
+ }
+
+cleanup:
+ if( dummy_buf )
+ {
+ free( dummy_buf );
+ }
+
+ return rv;
+}
+
+int spi_rdwr(spidev_t *spi, char *data, char *rbuf, int nbytes)
+{
+ int rv = 0;
+
+ struct spi_ioc_transfer tr =
+ {
+ .tx_buf = (unsigned long)data,
+ .rx_buf = (unsigned long)rbuf,
+ .len = nbytes,
+ .delay_usecs = spi->delay,
+ .speed_hz = spi->speed,
+ .bits_per_word = spi->bits,
+ };
+
+ if( !spi || !data || nbytes<=0 )
+ {
+ spi_dbg("Invalid input arguments\n");
+ return -1;
+ }
+
+
+ if ( spi->mode & (SPI_TX_QUAD|SPI_RX_QUAD) )
+ tr.tx_nbits = 4;
+
+ if ( spi->mode & (SPI_TX_DUAL|SPI_RX_DUAL) )
+ tr.tx_nbits = 2;
+
+ if (!(spi->mode & SPI_LOOP))
+ {
+ if (spi->mode & (SPI_TX_QUAD|SPI_TX_DUAL))
+ tr.rx_buf = 0;
+ else if (spi->mode & (SPI_RX_QUAD|SPI_RX_DUAL))
+ tr.tx_buf = 0;
+ }
+
+
+ if( ioctl(spi->fd, SPI_IOC_MESSAGE(1), &tr) < 0)
+ {
+ spi_dbg("spi_read SPI_IOC_MESSAGE failure: %s\n", strerror(errno));
+ rv = -3;
+ }
+
+ return rv;
+}
+
+int spi_term(spidev_t *spi)
+{
+ if( !spi )
+ {
+ spi_dbg("Invalid input arguments\n");
+ return -1;
+ }
+
+ if(spi->fd)
+ {
+ spi_dbg("close spi device '%s'\n", spi->devname);
+ close(spi->fd);
+ }
+
+ memset(spi, 0, sizeof(*spi));
+ spi->fd = -1;
+}
+
diff --git a/program/lylib/spidev.h b/program/lylib/spidev.h
new file mode 100644
index 0000000..84be549
--- /dev/null
+++ b/program/lylib/spidev.h
@@ -0,0 +1,75 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: spidev.h
+ * Description: This file is spidev user space API.
+ *
+ * Version: 1.0.0(2019年08月19日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年08月19日 23时18分54秒"
+ *
+ ********************************************************************************/
+#ifndef _SPIDEV_H_
+#define _SPIDEV_H_
+
+#include <stdint.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/ioctl.h>
+#include <sys/stat.h>
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
+#define DEVNAME_LEN 64
+
+#define DEF_SPI_BPW 8 /* bits per word */
+#define DEF_SPI_SPEED 500 /* unit kHZ */
+#define DEF_SPI_MODE SPI_CPHA
+
+//#define SPI_DEBUG
+#ifdef SPI_DEBUG
+#define spi_dbg(format,args...) printf(format, ##args)
+#else
+#define spi_dbg(format,args...) do{} while(0);
+#endif
+
+typedef struct spidev_s
+{
+ char devname[DEVNAME_LEN];
+ int fd;
+ uint8_t bits; /* bits per word */
+ uint32_t speed; /* max speed in HZ */
+ uint32_t delay; /* delay usecs */
+
+ /* mode: SPI_CPHA,SPI_CPOL => <SPI_MODE_0,SPI_MODE_1,SPI_MODE_2,SPI_MODE_3>
+ * SPI_CS_HIGH | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP | SPI_NO_CS
+ * | SPI_READY | SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD */
+ uint32_t mode;
+} spidev_t;
+
+
+/* initialise and open spidev context
+ * NOTE: $speed unit is KHz
+ */
+extern int spi_init(spidev_t *spi, char *spidev, uint8_t bpw, uint32_t speed, uint32_t delay, uint32_t mode);
+
+
+/* read size bytes from SPI slave */
+extern int spi_read(spidev_t *spi, char *buf, int size);
+
+
+/* write nbytes to SPI slave */
+extern int spi_write(spidev_t *spi, char *data, int nbytes);
+
+
+/* write nbytes and read nbytes to/from SPI slave */
+extern int spi_rdwr(spidev_t *spi, char *data, char *rbuf, int nbytes);
+
+
+/* terminate and close spidev context */
+extern int spi_term(spidev_t *spi);
+
+
+#endif /* ----- #ifndef _SPIDEV_H_ ----- */
+
--
Gitblit v1.9.1