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