選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

wiringPiSPI.c 6.0 KiB

6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
6ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * wiringPiSPI.c:
  3. * Simplified SPI access routines
  4. * Copyright (c) 2012-2015 Gordon Henderson
  5. ***********************************************************************
  6. * This file is part of wiringPi:
  7. * https://github.com/WiringPi/WiringPi/
  8. *
  9. * wiringPi is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * wiringPi is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with wiringPi.
  21. * If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************
  23. */
  24. #include <stdio.h>
  25. #include <unistd.h>
  26. #include <stdint.h>
  27. #include <stdlib.h>
  28. #include <fcntl.h>
  29. #include <errno.h>
  30. #include <string.h>
  31. #include <sys/ioctl.h>
  32. #include <asm/ioctl.h>
  33. #include <linux/spi/spidev.h>
  34. #include "wiringPi.h"
  35. #include "wiringPiSPI.h"
  36. // The SPI bus parameters
  37. // Variables as they need to be passed as pointers later on
  38. //static const char *spiDev0 = "/dev/spidev0.0" ;
  39. //static const char *spiDev1 = "/dev/spidev0.1" ;
  40. static const uint8_t spiBPW = 8 ;
  41. static const uint16_t spiDelay = 0 ;
  42. //https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf
  43. const uint8_t WPI_MaxSPINumbers = 7 ;
  44. const uint8_t WPI_MaxSPIChannels = 3 ;
  45. static uint32_t spiSpeeds [7][3] =
  46. {
  47. {0, 0, 0},
  48. {0, 0, 0},
  49. {0, 0, 0},
  50. {0, 0, 0},
  51. {0, 0, 0},
  52. {0, 0, 0},
  53. {0, 0, 0},
  54. };
  55. static int spiFds [7][3] =
  56. {
  57. {-1, -1, -1},
  58. {-1, -1, -1},
  59. {-1, -1, -1},
  60. {-1, -1, -1},
  61. {-1, -1, -1},
  62. {-1, -1, -1},
  63. {-1, -1, -1},
  64. };
  65. int SPICheckLimits(const int number, const int channel) {
  66. if (channel<0 || channel>=WPI_MaxSPIChannels) {
  67. fprintf (stderr, "wiringPiSPI: Invalid SPI channel (%d, valid range 0-%d)", channel, WPI_MaxSPIChannels-1);
  68. return -EINVAL;
  69. }
  70. if (number<0 || number>=WPI_MaxSPINumbers) {
  71. fprintf (stderr, "wiringPiSPI: Invalid SPI number (%d, valid range 0-%d)", number, WPI_MaxSPINumbers-1);
  72. return -EINVAL;
  73. }
  74. return 0; //sucess
  75. }
  76. #define RETURN_ON_LIMIT_FAIL int ret = SPICheckLimits(number, channel); if(ret!=0) { return ret; };
  77. /*
  78. * wiringPiSPIGetFd:
  79. * Return the file-descriptor for the given channel
  80. *********************************************************************************
  81. */
  82. int wiringPiSPIxGetFd(const int number, int channel)
  83. {
  84. if (SPICheckLimits(number, channel)!=0) {
  85. return -1;
  86. }
  87. return spiFds[number][channel];
  88. }
  89. int wiringPiSPIGetFd(int channel) {
  90. return wiringPiSPIxGetFd(0, channel);
  91. }
  92. /*
  93. * wiringPiSPIDataRW:
  94. * Write and Read a block of data over the SPI bus.
  95. * Note the data ia being read into the transmit buffer, so will
  96. * overwrite it!
  97. * This is also a full-duplex operation.
  98. *********************************************************************************
  99. */
  100. int wiringPiSPIxDataRW (const int number, const int channel, unsigned char *data, const int len)
  101. {
  102. RETURN_ON_LIMIT_FAIL
  103. if (-1==spiFds[number][channel]) {
  104. fprintf (stderr, "wiringPiSPI: Invalid SPI number/channel (need wiringPiSPIxSetupMode before read/write)");
  105. return -EBADF;
  106. }
  107. struct spi_ioc_transfer spi ;
  108. // Mentioned in spidev.h but not used in the original kernel documentation
  109. // test program )-:
  110. memset (&spi, 0, sizeof (spi)) ;
  111. spi.tx_buf = (unsigned long)data ;
  112. spi.rx_buf = (unsigned long)data ;
  113. spi.len = len ;
  114. spi.delay_usecs = spiDelay ;
  115. spi.speed_hz = spiSpeeds [number][channel] ;
  116. spi.bits_per_word = spiBPW ;
  117. return ioctl (spiFds[number][channel], SPI_IOC_MESSAGE(1), &spi) ;
  118. }
  119. int wiringPiSPIDataRW (int channel, unsigned char *data, int len) {
  120. return wiringPiSPIxDataRW(0, channel, data, len);
  121. }
  122. /*
  123. * wiringPiSPISetupMode:
  124. * Open the SPI device, and set it up, with the mode, etc.
  125. *********************************************************************************
  126. */
  127. int wiringPiSPIxSetupMode(const int number, const int channel, const int speed, const int mode)
  128. {
  129. int fd ;
  130. char spiDev [32] ;
  131. RETURN_ON_LIMIT_FAIL
  132. if (mode<0 || mode>3) { // Mode is 0, 1, 2 or 3 original
  133. fprintf (stderr, "wiringPiSPI: Invalid mode (%d, valid range 0-%d)", mode, 3);
  134. return -EINVAL;
  135. }
  136. snprintf (spiDev, 31, "/dev/spidev%d.%d", number, channel) ;
  137. if ((fd = open (spiDev, O_RDWR)) < 0) {
  138. return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device %s: %s\n", spiDev, strerror (errno)) ;
  139. }
  140. spiSpeeds [number][channel] = speed ;
  141. spiFds [number][channel] = fd ;
  142. // Set SPI parameters.
  143. if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0)
  144. return wiringPiFailure (WPI_ALMOST, "SPI mode change failure: %s\n", strerror (errno)) ;
  145. if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
  146. return wiringPiFailure (WPI_ALMOST, "SPI BPW change failure: %s\n", strerror (errno)) ;
  147. if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
  148. return wiringPiFailure (WPI_ALMOST, "SPI speed change failure: %s\n", strerror (errno)) ;
  149. return fd ;
  150. }
  151. int wiringPiSPISetupMode (int channel, int speed, int mode) {
  152. return wiringPiSPIxSetupMode (0, channel, speed, mode);
  153. }
  154. /*
  155. * wiringPiSPISetup:
  156. * Open the SPI device, and set it up, etc. in the default MODE 0
  157. *********************************************************************************
  158. */
  159. int wiringPiSPISetup (int channel, int speed) {
  160. return wiringPiSPIxSetupMode(0, channel, speed, 0) ;
  161. }
  162. int wiringPiSPIxClose (const int number, const int channel) {
  163. RETURN_ON_LIMIT_FAIL
  164. if (spiFds[number][channel]>0) {
  165. ret = close(spiFds[number][channel]);
  166. }
  167. spiSpeeds [number][channel] = 0 ;
  168. spiFds [number][channel] = -1 ;
  169. return ret;
  170. }
  171. int wiringPiSPIClose (const int channel) {
  172. return wiringPiSPIxClose (0, channel);
  173. }