sr595.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * sr595.c:
  3. * Extend wiringPi with the 74x595 shift register as a GPIO
  4. * expander chip.
  5. * Note that the code can cope with a number of 595's
  6. * daisy-chained together - up to 4 for now as we're storing
  7. * the output "register" in a single unsigned int.
  8. *
  9. * Copyright (c) 2013 Gordon Henderson
  10. ***********************************************************************
  11. * This file is part of wiringPi:
  12. * https://projects.drogon.net/raspberry-pi/wiringpi/
  13. *
  14. * wiringPi is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Lesser General Public License as
  16. * published by the Free Software Foundation, either version 3 of the
  17. * License, or (at your option) any later version.
  18. *
  19. * wiringPi is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU Lesser General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Lesser General Public
  25. * License along with wiringPi.
  26. * If not, see <http://www.gnu.org/licenses/>.
  27. ***********************************************************************
  28. */
  29. #include <stdio.h>
  30. #include <stdint.h>
  31. #include "wiringPi.h"
  32. #include "sr595.h"
  33. /*
  34. * myDigitalWrite:
  35. *********************************************************************************
  36. */
  37. static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
  38. {
  39. unsigned int mask ;
  40. int dataPin, clockPin, latchPin ;
  41. int bit, bits, output ;
  42. pin -= node->pinBase ; // Normalise pin number
  43. bits = node->pinMax - node->pinBase + 1 ; // ie. number of clock pulses
  44. dataPin = node->data0 ;
  45. clockPin = node->data1 ;
  46. latchPin = node->data2 ;
  47. output = node->data3 ;
  48. mask = 1 << pin ;
  49. if (value == LOW)
  50. output &= (~mask) ;
  51. else
  52. output |= mask ;
  53. node->data3 = output ;
  54. // A low -> high latch transition copies the latch to the output pins
  55. digitalWrite (latchPin, LOW) ; delayMicroseconds (1) ;
  56. for (bit = bits - 1 ; bit >= 0 ; --bit)
  57. {
  58. digitalWrite (dataPin, output & (1 << bit)) ;
  59. digitalWrite (clockPin, HIGH) ; delayMicroseconds (1) ;
  60. digitalWrite (clockPin, LOW) ; delayMicroseconds (1) ;
  61. }
  62. digitalWrite (latchPin, HIGH) ; delayMicroseconds (1) ;
  63. }
  64. /*
  65. * sr595Setup:
  66. * Create a new instance of a 74x595 shift register GPIO expander.
  67. *********************************************************************************
  68. */
  69. int sr595Setup (const int pinBase, const int numPins,
  70. const int dataPin, const int clockPin, const int latchPin)
  71. {
  72. struct wiringPiNodeStruct *node ;
  73. node = wiringPiNewNode (pinBase, numPins) ;
  74. node->data0 = dataPin ;
  75. node->data1 = clockPin ;
  76. node->data2 = latchPin ;
  77. node->data3 = 0 ; // Output register
  78. node->digitalWrite = myDigitalWrite ;
  79. // Initialise the underlying hardware
  80. digitalWrite (dataPin, LOW) ;
  81. digitalWrite (clockPin, LOW) ;
  82. digitalWrite (latchPin, HIGH) ;
  83. pinMode (dataPin, OUTPUT) ;
  84. pinMode (clockPin, OUTPUT) ;
  85. pinMode (latchPin, OUTPUT) ;
  86. return TRUE ;
  87. }