mcp23008.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * mcp23008.c:
  3. * Extend wiringPi with the MCP 23008 I2C GPIO expander chip
  4. * Copyright (c) 2013 Gordon Henderson
  5. ***********************************************************************
  6. * This file is part of wiringPi:
  7. * https://projects.drogon.net/raspberry-pi/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 <pthread.h>
  26. #include "wiringPi.h"
  27. #include "wiringPiI2C.h"
  28. #include "mcp23x0817.h"
  29. #include "mcp23008.h"
  30. /*
  31. * myPinMode:
  32. *********************************************************************************
  33. */
  34. static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
  35. {
  36. int mask, old, reg ;
  37. reg = MCP23x08_IODIR ;
  38. mask = 1 << (pin - node->pinBase) ;
  39. old = wiringPiI2CReadReg8 (node->fd, reg) ;
  40. if (mode == OUTPUT)
  41. old &= (~mask) ;
  42. else
  43. old |= mask ;
  44. wiringPiI2CWriteReg8 (node->fd, reg, old) ;
  45. }
  46. /*
  47. * myPullUpDnControl:
  48. *********************************************************************************
  49. */
  50. static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
  51. {
  52. int mask, old, reg ;
  53. reg = MCP23x08_GPPU ;
  54. mask = 1 << (pin - node->pinBase) ;
  55. old = wiringPiI2CReadReg8 (node->fd, reg) ;
  56. if (mode == PUD_UP)
  57. old |= mask ;
  58. else
  59. old &= (~mask) ;
  60. wiringPiI2CWriteReg8 (node->fd, reg, old) ;
  61. }
  62. /*
  63. * myDigitalWrite:
  64. *********************************************************************************
  65. */
  66. static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
  67. {
  68. int bit, old ;
  69. bit = 1 << ((pin - node->pinBase) & 7) ;
  70. old = node->data2 ;
  71. if (value == LOW)
  72. old &= (~bit) ;
  73. else
  74. old |= bit ;
  75. wiringPiI2CWriteReg8 (node->fd, MCP23x08_GPIO, old) ;
  76. node->data2 = old ;
  77. }
  78. /*
  79. * myDigitalRead:
  80. *********************************************************************************
  81. */
  82. static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
  83. {
  84. int mask, value ;
  85. mask = 1 << ((pin - node->pinBase) & 7) ;
  86. value = wiringPiI2CReadReg8 (node->fd, MCP23x08_GPIO) ;
  87. if ((value & mask) == 0)
  88. return LOW ;
  89. else
  90. return HIGH ;
  91. }
  92. /*
  93. * mcp23008Setup:
  94. * Create a new instance of an MCP23008 I2C GPIO interface. We know it
  95. * has 8 pins, so all we need to know here is the I2C address and the
  96. * user-defined pin base.
  97. *********************************************************************************
  98. */
  99. int mcp23008Setup (const int pinBase, const int i2cAddress)
  100. {
  101. int fd ;
  102. struct wiringPiNodeStruct *node ;
  103. if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
  104. return FALSE ;
  105. wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ;
  106. node = wiringPiNewNode (pinBase, 8) ;
  107. node->fd = fd ;
  108. node->pinMode = myPinMode ;
  109. node->pullUpDnControl = myPullUpDnControl ;
  110. node->digitalRead = myDigitalRead ;
  111. node->digitalWrite = myDigitalWrite ;
  112. node->data2 = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ;
  113. return TRUE ;
  114. }