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

gertboard.c 4.4 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * gertboard.c:
  3. * Access routines for the SPI devices on the Gertboard
  4. * Copyright (c) 2012 Gordon Henderson
  5. *
  6. * The Gertboard has:
  7. *
  8. * An MCP3002 dual-channel A to D convertor connected
  9. * to the SPI bus, selected by chip-select A, and:
  10. *
  11. * An MCP4802 dual-channel D to A convertor connected
  12. * to the SPI bus, selected via chip-select B.
  13. *
  14. ***********************************************************************
  15. * This file is part of wiringPi:
  16. * https://projects.drogon.net/raspberry-pi/wiringpi/
  17. *
  18. * wiringPi is free software: you can redistribute it and/or modify
  19. * it under the terms of the GNU Lesser General Public License as
  20. * published by the Free Software Foundation, either version 3 of the
  21. * License, or (at your option) any later version.
  22. *
  23. * wiringPi is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU Lesser General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU Lesser General Public
  29. * License along with wiringPi.
  30. * If not, see <http://www.gnu.org/licenses/>.
  31. ***********************************************************************
  32. */
  33. #include <stdio.h>
  34. #include <stdint.h>
  35. #include <fcntl.h>
  36. #include <sys/ioctl.h>
  37. #include <linux/spi/spidev.h>
  38. #include "gertboard.h"
  39. // The SPI bus parameters
  40. // Variables as they need to be passed as pointers later on
  41. static char *spiA2D = "/dev/spidev0.0" ;
  42. static char *spiD2A = "/dev/spidev0.1" ;
  43. static uint8_t spiMode = 0 ;
  44. static uint8_t spiBPW = 8 ;
  45. static uint32_t spiSpeed = 100000 ; // 1MHz
  46. static uint16_t spiDelay = 0;
  47. // Locals here to keep track of everything
  48. static int spiFdA2D ;
  49. static int spiFdD2A ;
  50. /*
  51. * gertboardAnalogWrite:
  52. * Write an 8-bit data value to the MCP4802 Analog to digital
  53. * convertor on the Gertboard.
  54. *********************************************************************************
  55. */
  56. void gertboardAnalogWrite (int chan, int value)
  57. {
  58. uint8_t spiBufTx [2] ;
  59. uint8_t spiBufRx [2] ;
  60. struct spi_ioc_transfer spi ;
  61. uint8_t chanBits, dataBits ;
  62. if (chan == 0)
  63. chanBits = 0x30 ;
  64. else
  65. chanBits = 0xB0 ;
  66. chanBits |= ((value >> 4) & 0x0F) ;
  67. dataBits = ((value << 4) & 0xF0) ;
  68. spiBufTx [0] = chanBits ;
  69. spiBufTx [1] = dataBits ;
  70. spi.tx_buf = (unsigned long)spiBufTx ;
  71. spi.rx_buf = (unsigned long)spiBufRx ;
  72. spi.len = 2 ;
  73. spi.delay_usecs = spiDelay ;
  74. spi.speed_hz = spiSpeed ;
  75. spi.bits_per_word = spiBPW ;
  76. ioctl (spiFdD2A, SPI_IOC_MESSAGE(1), &spi) ;
  77. }
  78. /*
  79. * gertboardAnalogRead:
  80. * Return the analog value of the given channel (0/1).
  81. * The A/D is a 10-bit device
  82. *********************************************************************************
  83. */
  84. int gertboardAnalogRead (int chan)
  85. {
  86. uint8_t spiBufTx [4] ;
  87. uint8_t spiBufRx [4] ;
  88. struct spi_ioc_transfer spi ;
  89. uint8_t chanBits ;
  90. if (chan == 0)
  91. chanBits = 0b0110100 ;
  92. else
  93. chanBits = 0b0111100 ;
  94. spiBufTx [0] = chanBits ;
  95. spiBufTx [1] = 0 ;
  96. spi.tx_buf = (unsigned long)spiBufTx ;
  97. spi.rx_buf = (unsigned long)spiBufRx ;
  98. spi.len = 4 ;
  99. spi.delay_usecs = spiDelay ;
  100. spi.speed_hz = spiSpeed ;
  101. spi.bits_per_word = spiBPW ;
  102. ioctl (spiFdA2D, SPI_IOC_MESSAGE(1), &spi) ;
  103. return spiBufRx [0] << 8 | spiBufRx [1] ;
  104. }
  105. /*
  106. * setParams:
  107. * Output the SPI bus parameters to the given device
  108. *********************************************************************************
  109. */
  110. static int setParams (int fd)
  111. {
  112. if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0)
  113. return -1 ;
  114. if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0)
  115. return -1 ;
  116. if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
  117. return -1 ;
  118. if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0)
  119. return -1 ;
  120. if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0)
  121. return -1 ;
  122. if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0)
  123. return -1 ;
  124. return 0 ;
  125. }
  126. /*
  127. * gertboardSPISetup:
  128. * Initialise the SPI bus, etc.
  129. *********************************************************************************
  130. */
  131. int gertboardSPISetup (void)
  132. {
  133. if ((spiFdA2D = open (spiA2D, O_RDWR)) < 0)
  134. return -1 ;
  135. if (setParams (spiFdA2D) != 0)
  136. return -1 ;
  137. if ((spiFdD2A = open (spiD2A, O_RDWR)) < 0)
  138. return -1 ;
  139. if (setParams (spiFdD2A) != 0)
  140. return -1 ;
  141. return 0 ;
  142. }