waveshare_epaper

Waveshare e-paper display shenanigans
git clone git://bsandro.tech/waveshare_epaper
Log | Files | Refs | README

dev_hardware_SPI.c (11882B)


      1 /*****************************************************************************
      2 * | File        :   dev_hardware_SPI.c
      3 * | Author      :   Waveshare team
      4 * | Function    :   Read and write /dev/SPI,  hardware SPI
      5 * | Info        :
      6 *----------------
      7 * |	This version:   V1.0
      8 * | Date        :   2019-06-26
      9 * | Info        :   Basic version
     10 *
     11 #
     12 # Permission is hereby granted, free of charge, to any person obtaining a copy
     13 # of this software and associated documnetation files (the "Software"), to deal
     14 # in the Software without restriction, including without limitation the rights
     15 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     16 # copies of the Software, and to permit persons to  whom the Software is
     17 # furished to do so, subject to the following conditions:
     18 #
     19 # The above copyright notice and this permission notice shall be included in
     20 # all copies or substantial portions of the Software.
     21 #
     22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     24 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     25 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     26 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     27 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     28 # THE SOFTWARE.
     29 #
     30 ******************************************************************************/
     31 #include "dev_hardware_SPI.h"
     32 
     33 
     34 #include <stdlib.h>
     35 #include <stdio.h>
     36 
     37 #include <stdint.h> 
     38 #include <unistd.h> 
     39 #include <stdio.h> 
     40 #include <stdlib.h> 
     41 #include <getopt.h> 
     42 #include <fcntl.h> 
     43 #include <sys/ioctl.h> 
     44 #include <linux/types.h> 
     45 #include <linux/spi/spidev.h> 
     46 
     47 HARDWARE_SPI hardware_SPI;
     48 
     49 static uint8_t bits = 8; 
     50 
     51 #define SPI_CS_HIGH     0x04                //Chip select high  
     52 #define SPI_LSB_FIRST   0x08                //LSB  
     53 #define SPI_3WIRE       0x10                //3-wire mode SI and SO same line
     54 #define SPI_LOOP        0x20                //Loopback mode  
     55 #define SPI_NO_CS       0x40                //A single device occupies one SPI bus, so there is no chip select 
     56 #define SPI_READY       0x80                //Slave pull low to stop data transmission  
     57 
     58 struct spi_ioc_transfer tr;
     59 
     60 
     61 /******************************************************************************
     62 function:   SPI port initialization
     63 parameter:
     64     SPI_device : Device name
     65 Info:
     66     /dev/spidev0.0 
     67     /dev/spidev0.1
     68 ******************************************************************************/
     69 void DEV_HARDWARE_SPI_begin(char *SPI_device)
     70 {
     71     //device
     72     int ret = 0; 
     73     if((hardware_SPI.fd = open(SPI_device, O_RDWR )) < 0)  {
     74         perror("Failed to open SPI device.\n");  
     75         DEV_HARDWARE_SPI_Debug("Failed to open SPI device\r\n");
     76         exit(1); 
     77     } else {
     78         DEV_HARDWARE_SPI_Debug("open : %s\r\n", SPI_device);
     79     }
     80     hardware_SPI.mode = 0;
     81     
     82     ret = ioctl(hardware_SPI.fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
     83     if (ret == -1) {
     84         DEV_HARDWARE_SPI_Debug("can't set bits per word\r\n"); 
     85     }
     86  
     87     ret = ioctl(hardware_SPI.fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
     88     if (ret == -1) {
     89         DEV_HARDWARE_SPI_Debug("can't get bits per word\r\n"); 
     90     }
     91     tr.bits_per_word = bits;
     92     
     93     DEV_HARDWARE_SPI_Mode(SPI_MODE_0);
     94     DEV_HARDWARE_SPI_ChipSelect(SPI_CS_Mode_LOW);
     95     DEV_HARDWARE_SPI_SetBitOrder(SPI_BIT_ORDER_LSBFIRST);
     96     DEV_HARDWARE_SPI_setSpeed(20000000);
     97     DEV_HARDWARE_SPI_SetDataInterval(0);
     98 }
     99 
    100 void DEV_HARDWARE_SPI_beginSet(char *SPI_device, SPIMode mode, uint32_t speed)
    101 {
    102     //device
    103     int ret = 0; 
    104     hardware_SPI.mode = 0;
    105     if((hardware_SPI.fd = open(SPI_device, O_RDWR )) < 0)  {
    106         perror("Failed to open SPI device.\n");  
    107         exit(1); 
    108     } else {
    109         DEV_HARDWARE_SPI_Debug("open : %s\r\n", SPI_device);
    110     }
    111     
    112     ret = ioctl(hardware_SPI.fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    113     if (ret == -1) 
    114         DEV_HARDWARE_SPI_Debug("can't set bits per word\r\n"); 
    115  
    116     ret = ioctl(hardware_SPI.fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    117     if (ret == -1) 
    118         DEV_HARDWARE_SPI_Debug("can't get bits per word\r\n"); 
    119 
    120     DEV_HARDWARE_SPI_Mode(mode);
    121     DEV_HARDWARE_SPI_ChipSelect(SPI_CS_Mode_LOW);
    122     DEV_HARDWARE_SPI_setSpeed(speed);
    123     DEV_HARDWARE_SPI_SetDataInterval(0);
    124 }
    125 
    126 
    127 /******************************************************************************
    128 function:   SPI device End
    129 parameter:
    130 Info:
    131 ******************************************************************************/
    132 void DEV_HARDWARE_SPI_end(void)
    133 {
    134     hardware_SPI.mode = 0;
    135     if (close(hardware_SPI.fd) != 0){
    136         DEV_HARDWARE_SPI_Debug("Failed to close SPI device\r\n");
    137         perror("Failed to close SPI device.\n");  
    138     }
    139 }
    140 
    141 /******************************************************************************
    142 function:   Set SPI speed
    143 parameter:
    144 Info:   Return 1 success 
    145         Return -1 failed
    146 ******************************************************************************/
    147 int DEV_HARDWARE_SPI_setSpeed(uint32_t speed)
    148 {
    149     uint32_t speed1 = hardware_SPI.speed;
    150     
    151     hardware_SPI.speed = speed;
    152 
    153     //Write speed
    154     if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
    155         DEV_HARDWARE_SPI_Debug("can't set max speed hz\r\n"); 
    156         hardware_SPI.speed = speed1;//Setting failure rate unchanged
    157         return -1;
    158     }
    159     
    160     //Read the speed of just writing
    161     if (ioctl(hardware_SPI.fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) {
    162         DEV_HARDWARE_SPI_Debug("can't get max speed hz\r\n"); 
    163         hardware_SPI.speed = speed1;//Setting failure rate unchanged
    164         return -1;
    165     }
    166     hardware_SPI.speed = speed;
    167     tr.speed_hz = hardware_SPI.speed;
    168     return 1;
    169 }
    170 
    171 /******************************************************************************
    172 function:   Set SPI Mode
    173 parameter:
    174 Info:  
    175     SPIMode:
    176         SPI_MODE0 
    177         SPI_MODE1 
    178         SPI_MODE2 
    179         SPI_MODE3
    180     Return :
    181         Return 1 success 
    182         Return -1 failed
    183 ******************************************************************************/
    184 int DEV_HARDWARE_SPI_Mode(SPIMode mode)
    185 {
    186     hardware_SPI.mode &= 0xfC;//Clear low 2 digits
    187     hardware_SPI.mode |= mode;//Setting mode
    188     
    189     //Write device
    190     if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
    191         DEV_HARDWARE_SPI_Debug("can't set spi mode\r\n"); 
    192         return -1;
    193     }
    194     return 1;
    195 }
    196 
    197 /******************************************************************************
    198 function:   Set SPI CS Enable
    199 parameter:
    200 Info:  
    201     EN:
    202         DISABLE 
    203         ENABLE 
    204     Return :
    205         Return 1 success 
    206         Return -1 failed
    207 ******************************************************************************/
    208 int DEV_HARDWARE_SPI_CSEN(SPICSEN EN)
    209 {
    210     if(EN == ENABLE){
    211         hardware_SPI.mode |= SPI_NO_CS;
    212     }else {
    213         hardware_SPI.mode &= ~SPI_NO_CS;
    214     }
    215     //Write device
    216     if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
    217         DEV_HARDWARE_SPI_Debug("can't set spi CS EN\r\n"); 
    218         return -1;
    219     }
    220     return 1;
    221 }
    222 
    223 /******************************************************************************
    224 function:   Chip Select
    225 parameter:
    226 Info:  
    227     CS_Mode:
    228         SPI_CS_Mode_LOW
    229         SPI_CS_Mode_HIGH
    230         SPI_CS_Mode_NONE
    231     Return :
    232         Return 1 success 
    233         Return -1 failed
    234 ******************************************************************************/
    235 int DEV_HARDWARE_SPI_ChipSelect(SPIChipSelect CS_Mode)
    236 {
    237     if(CS_Mode == SPI_CS_Mode_HIGH){
    238         hardware_SPI.mode |= SPI_CS_HIGH;
    239         hardware_SPI.mode &= ~SPI_NO_CS;
    240         DEV_HARDWARE_SPI_Debug("CS HIGH \r\n");
    241     }else if(CS_Mode == SPI_CS_Mode_LOW){
    242         hardware_SPI.mode &= ~SPI_CS_HIGH;
    243         hardware_SPI.mode &= ~SPI_NO_CS;
    244     }else if(CS_Mode == SPI_CS_Mode_NONE){
    245         hardware_SPI.mode |= SPI_NO_CS;
    246     }
    247     
    248     if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
    249         DEV_HARDWARE_SPI_Debug("can't set spi mode\r\n"); 
    250         return -1;
    251     }
    252     return 1;
    253 }
    254 
    255 /******************************************************************************
    256 function:   Sets the SPI bit order
    257 parameter:
    258 Info:  
    259     Order:
    260         SPI_BIT_ORDER_LSBFIRST
    261         SPI_BIT_ORDER_MSBFIRST
    262     Return :
    263         Return 1 success 
    264         Return -1 failed
    265 ******************************************************************************/
    266 int DEV_HARDWARE_SPI_SetBitOrder(SPIBitOrder Order)
    267 {
    268     if(Order == SPI_BIT_ORDER_LSBFIRST){
    269         hardware_SPI.mode |= SPI_LSB_FIRST;
    270         DEV_HARDWARE_SPI_Debug("SPI_LSB_FIRST\r\n");
    271     }else if(Order == SPI_BIT_ORDER_MSBFIRST){
    272         hardware_SPI.mode &= ~SPI_LSB_FIRST;
    273         DEV_HARDWARE_SPI_Debug("SPI_MSB_FIRST\r\n");
    274     }
    275     
    276     // DEV_HARDWARE_SPI_Debug("hardware_SPI.mode = 0x%02x\r\n", hardware_SPI.mode);
    277     int fd = ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode);
    278     DEV_HARDWARE_SPI_Debug("fd = %d\r\n",fd);
    279     if (fd == -1) {
    280         DEV_HARDWARE_SPI_Debug("can't set spi SPI_LSB_FIRST\r\n"); 
    281         return -1;
    282     }
    283     return 1;
    284 }
    285 
    286 /******************************************************************************
    287 function:   Sets the SPI Bus Mode
    288 parameter:
    289 Info:  
    290     Order:
    291         SPI_3WIRE_Mode
    292         SPI_4WIRE_Mode
    293     Return :
    294         Return 1 success 
    295         Return -1 failed
    296 ******************************************************************************/
    297 int DEV_HARDWARE_SPI_SetBusMode(BusMode mode)
    298 {
    299     if(mode == SPI_3WIRE_Mode){
    300         hardware_SPI.mode |= SPI_3WIRE;
    301     }else if(mode == SPI_4WIRE_Mode){
    302         hardware_SPI.mode &= ~SPI_3WIRE;
    303     }
    304     if (ioctl(hardware_SPI.fd, SPI_IOC_WR_MODE, &hardware_SPI.mode) == -1) {
    305         DEV_HARDWARE_SPI_Debug("can't set spi mode\r\n"); 
    306         return -1;
    307     }
    308     return 1;
    309 }
    310 
    311 /******************************************************************************
    312 function: 
    313     Time interval after transmission of one byte during continuous transmission
    314 parameter:
    315     us :   Interval time (us)
    316 Info:
    317 ******************************************************************************/
    318 void DEV_HARDWARE_SPI_SetDataInterval(uint16_t us)
    319 {
    320     hardware_SPI.delay = us;
    321     tr.delay_usecs  = hardware_SPI.delay;
    322 }
    323 
    324 /******************************************************************************
    325 function: SPI port sends one byte of data
    326 parameter:
    327     buf :   Sent data
    328 Info:
    329 ******************************************************************************/
    330 uint8_t DEV_HARDWARE_SPI_TransferByte(uint8_t buf)
    331 {
    332     uint8_t rbuf[1];
    333     tr.len = 1;
    334     tr.tx_buf =  (unsigned long)&buf;
    335     tr.rx_buf =  (unsigned long)rbuf;
    336     
    337     //ioctl Operation, transmission of data
    338     if ( ioctl(hardware_SPI.fd, SPI_IOC_MESSAGE(1), &tr) < 1 )  
    339         DEV_HARDWARE_SPI_Debug("can't send spi message\r\n"); 
    340     return rbuf[0];
    341 }
    342 
    343 /******************************************************************************
    344 function: The SPI port reads a byte
    345 parameter:
    346 Info: Return read data
    347 ******************************************************************************/
    348 int DEV_HARDWARE_SPI_Transfer(uint8_t *buf, uint32_t len)
    349 {
    350     tr.len = len;
    351     tr.tx_buf =  (unsigned long)buf;
    352     tr.rx_buf =  (unsigned long)buf;
    353     
    354     //ioctl Operation, transmission of data
    355     if (ioctl(hardware_SPI.fd, SPI_IOC_MESSAGE(1), &tr)  < 1 ){  
    356         DEV_HARDWARE_SPI_Debug("can't send spi message\r\n"); 
    357         return -1;
    358     }
    359     
    360     return 1;
    361 }
    362