gertboard.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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 <wiringPi.h>
  39. #include <wiringPiSPI.h>
  40. #include "gertboard.h"
  41. // The A-D convertor won't run at more than 1MHz @ 3.3v
  42. #define SPI_ADC_SPEED 1000000
  43. #define SPI_DAC_SPEED 1000000
  44. #define SPI_A2D 0
  45. #define SPI_D2A 1
  46. /*
  47. * gertboardAnalogWrite:
  48. * Write an 8-bit data value to the MCP4802 Analog to digital
  49. * convertor on the Gertboard.
  50. *********************************************************************************
  51. */
  52. void gertboardAnalogWrite (const int chan, const int value)
  53. {
  54. uint8_t spiData [2] ;
  55. uint8_t chanBits, dataBits ;
  56. if (chan == 0)
  57. chanBits = 0x30 ;
  58. else
  59. chanBits = 0xB0 ;
  60. chanBits |= ((value >> 4) & 0x0F) ;
  61. dataBits = ((value << 4) & 0xF0) ;
  62. spiData [0] = chanBits ;
  63. spiData [1] = dataBits ;
  64. wiringPiSPIDataRW (SPI_D2A, spiData, 2) ;
  65. }
  66. /*
  67. * gertboardAnalogRead:
  68. * Return the analog value of the given channel (0/1).
  69. * The A/D is a 10-bit device
  70. *********************************************************************************
  71. */
  72. int gertboardAnalogRead (const int chan)
  73. {
  74. uint8_t spiData [2] ;
  75. uint8_t chanBits ;
  76. if (chan == 0)
  77. chanBits = 0b11010000 ;
  78. else
  79. chanBits = 0b11110000 ;
  80. spiData [0] = chanBits ;
  81. spiData [1] = 0 ;
  82. wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;
  83. return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ;
  84. }
  85. /*
  86. * gertboardSPISetup:
  87. * Initialise the SPI bus, etc.
  88. *********************************************************************************
  89. */
  90. int gertboardSPISetup (void)
  91. {
  92. if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0)
  93. return -1 ;
  94. if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0)
  95. return -1 ;
  96. return 0 ;
  97. }
  98. /*
  99. * New wiringPi node extension methods.
  100. *********************************************************************************
  101. */
  102. static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan)
  103. {
  104. return gertboardAnalogRead (chan - node->pinBase) ;
  105. }
  106. static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value)
  107. {
  108. gertboardAnalogWrite (chan - node->pinBase, value) ;
  109. }
  110. /*
  111. * gertboardAnalogSetup:
  112. * Create a new wiringPi device node for the analog devices on the
  113. * Gertboard. We create one node with 2 pins - each pin being read
  114. * and write - although the operations actually go to different
  115. * hardware devices.
  116. *********************************************************************************
  117. */
  118. int gertboardAnalogSetup (const int pinBase)
  119. {
  120. struct wiringPiNodeStruct *node ;
  121. int x ;
  122. if (( x = gertboardSPISetup ()) != 0)
  123. return x;
  124. node = wiringPiNewNode (pinBase, 2) ;
  125. node->analogRead = myAnalogRead ;
  126. node->analogWrite = myAnalogWrite ;
  127. return 0 ;
  128. }