| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /*****************************************************************************
- * | 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");
- printf("Failed to open SPI device\r\n");
- DEV_HARDWARE_SPI_Debug("Failed to open SPI device\r\n");
- exit(1);
- } else {
- printf("open : %s\r\n", SPI_device);
- 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) {
- printf("can't set bits per word\r\n");
- 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) {
- printf("can't get bits per word\r\n");
- 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(5);
- }
- 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)
- {
- tr.len = len;
- tr.tx_buf = (unsigned long)buf;
- tr.rx_buf = (unsigned long)buf;
-
- //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;
- }
|