mcp23017.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * mcp23017.c:
  3. * Extend wiringPi with the MCP 23017 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 "mcp23017.h"
  30. /*
  31. * myPinMode:
  32. *********************************************************************************
  33. */
  34. static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode)
  35. {
  36. int mask, old, reg ;
  37. pin -= node->pinBase ;
  38. if (pin < 8) // Bank A
  39. reg = MCP23x17_IODIRA ;
  40. else
  41. {
  42. reg = MCP23x17_IODIRB ;
  43. pin &= 0x07 ;
  44. }
  45. mask = 1 << pin ;
  46. old = wiringPiI2CReadReg8 (node->fd, reg) ;
  47. if (mode == OUTPUT)
  48. old &= (~mask) ;
  49. else
  50. old |= mask ;
  51. wiringPiI2CWriteReg8 (node->fd, reg, old) ;
  52. }
  53. /*
  54. * myPullUpDnControl:
  55. *********************************************************************************
  56. */
  57. static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode)
  58. {
  59. int mask, old, reg ;
  60. pin -= node->pinBase ;
  61. if (pin < 8) // Bank A
  62. reg = MCP23x17_GPPUA ;
  63. else
  64. {
  65. reg = MCP23x17_GPPUB ;
  66. pin &= 0x07 ;
  67. }
  68. mask = 1 << pin ;
  69. old = wiringPiI2CReadReg8 (node->fd, reg) ;
  70. if (mode == PUD_UP)
  71. old |= mask ;
  72. else
  73. old &= (~mask) ;
  74. wiringPiI2CWriteReg8 (node->fd, reg, old) ;
  75. }
  76. /*
  77. * myDigitalWrite:
  78. *********************************************************************************
  79. */
  80. static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value)
  81. {
  82. int bit, old ;
  83. pin -= node->pinBase ; // Pin now 0-15
  84. bit = 1 << (pin & 7) ;
  85. if (pin < 8) // Bank A
  86. {
  87. old = node->data2 ;
  88. if (value == LOW)
  89. old &= (~bit) ;
  90. else
  91. old |= bit ;
  92. wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOA, old) ;
  93. node->data2 = old ;
  94. }
  95. else // Bank B
  96. {
  97. old = node->data3 ;
  98. if (value == LOW)
  99. old &= (~bit) ;
  100. else
  101. old |= bit ;
  102. wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, old) ;
  103. node->data3 = old ;
  104. }
  105. }
  106. /*
  107. * myDigitalRead:
  108. *********************************************************************************
  109. */
  110. static int myDigitalRead (struct wiringPiNodeStruct *node, int pin)
  111. {
  112. int mask, value, gpio ;
  113. pin -= node->pinBase ;
  114. if (pin < 8) // Bank A
  115. gpio = MCP23x17_GPIOA ;
  116. else
  117. {
  118. gpio = MCP23x17_GPIOB ;
  119. pin &= 0x07 ;
  120. }
  121. mask = 1 << pin ;
  122. value = wiringPiI2CReadReg8 (node->fd, gpio) ;
  123. if ((value & mask) == 0)
  124. return LOW ;
  125. else
  126. return HIGH ;
  127. }
  128. /*
  129. * mcp23017Setup:
  130. * Create a new instance of an MCP23017 I2C GPIO interface. We know it
  131. * has 16 pins, so all we need to know here is the I2C address and the
  132. * user-defined pin base.
  133. *********************************************************************************
  134. */
  135. int mcp23017Setup (const int pinBase, const int i2cAddress)
  136. {
  137. int fd ;
  138. struct wiringPiNodeStruct *node ;
  139. if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
  140. return FALSE ;
  141. wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ;
  142. node = wiringPiNewNode (pinBase, 16) ;
  143. node->fd = fd ;
  144. node->pinMode = myPinMode ;
  145. node->pullUpDnControl = myPullUpDnControl ;
  146. node->digitalRead = myDigitalRead ;
  147. node->digitalWrite = myDigitalWrite ;
  148. node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ;
  149. node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ;
  150. return TRUE ;
  151. }