ioexpander.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /****************************************************************************
  2. * include/nuttx/ioexpander/ioexpander.h
  3. *
  4. * Copyright (C) 2015-2016, 2018 Gregory Nutt. All rights reserved.
  5. * Author: Sebastien Lorquet <sebastien@lorquet.fr>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. #ifndef __INCLUDE_NUTTX_IOEXPANDER_IOEXPANDER_H
  36. #define __INCLUDE_NUTTX_IOEXPANDER_IOEXPANDER_H
  37. /****************************************************************************
  38. * Included Files
  39. ****************************************************************************/
  40. #include <nuttx/config.h>
  41. #include <stdbool.h>
  42. #include <stdint.h>
  43. #ifdef CONFIG_IOEXPANDER
  44. /****************************************************************************
  45. * Pre-processor Definitions
  46. ****************************************************************************/
  47. /* Configuration ************************************************************/
  48. #ifndef CONFIG_IOEXPANDER_NPINS
  49. # define CONFIG_IOEXPANDER_NPINS 16
  50. #endif
  51. /* Pin definitions **********************************************************/
  52. #define IOEXPANDER_DIRECTION_IN 0 /* float */
  53. #define IOEXPANDER_DIRECTION_IN_PULLUP 1
  54. #define IOEXPANDER_DIRECTION_IN_PULLDOWN 2
  55. #define IOEXPANDER_DIRECTION_OUT 3 /* push-pull */
  56. #define IOEXPANDER_DIRECTION_OUT_OPENDRAIN 4
  57. #define IOEXPANDER_PINMASK (((ioe_pinset_t)1 << CONFIG_IOEXPANDER_NPINS) - 1)
  58. #define PINSET_ALL (~((ioe_pinset_t)0))
  59. /* Pin options */
  60. #define IOEXPANDER_OPTION_INVERT 1 /* Set the "active" level for a pin */
  61. # define IOEXPANDER_VAL_NORMAL 0 /* Normal, no inversion */
  62. # define IOEXPANDER_VAL_INVERT 1 /* Inverted */
  63. #define IOEXPANDER_OPTION_INTCFG 2 /* Configure interrupt for a pin */
  64. # define IOEXPANDER_VAL_DISABLE 0 /* 0000 Disable pin interrupts */
  65. # define IOEXPANDER_VAL_LEVEL 1 /* xx01 Interrupt on level (vs. edge) */
  66. # define IOEXPANDER_VAL_HIGH 5 /* 0101 Interrupt on high level */
  67. # define IOEXPANDER_VAL_LOW 9 /* 1001 Interrupt on low level */
  68. # define IOEXPANDER_VAL_EDGE 2 /* xx10 Interrupt on edge (vs. level) */
  69. # define IOEXPANDER_VAL_RISING 6 /* 0110 Interrupt on rising edge */
  70. # define IOEXPANDER_VAL_FALLING 10 /* 1010 Interrupt on falling edge */
  71. # define IOEXPANDER_VAL_BOTH 14 /* 1110 Interrupt on both edges */
  72. /* Access macros ************************************************************/
  73. /****************************************************************************
  74. * Name: IOEXP_SETDIRECTION
  75. *
  76. * Description:
  77. * Set the direction of an ioexpander pin. Required.
  78. *
  79. * Input Parameters:
  80. * dev - Device-specific state data
  81. * pin - The index of the pin to alter in this call
  82. * dir - One of the IOEXPANDER_DIRECTION_ macros
  83. *
  84. * Returned Value:
  85. * 0 on success, else a negative error code
  86. *
  87. ****************************************************************************/
  88. #define IOEXP_SETDIRECTION(dev,pin,dir) ((dev)->ops->ioe_direction(dev,pin,dir))
  89. /****************************************************************************
  90. * Name: IOEXP_SETOPTION
  91. *
  92. * Description:
  93. * Set pin options. Required.
  94. * Since all IO expanders have various pin options, this API allows setting
  95. * pin options in a flexible way.
  96. *
  97. * Input Parameters:
  98. * dev - Device-specific state data
  99. * pin - The index of the pin to alter in this call
  100. * opt - One of the IOEXPANDER_OPTION_ macros
  101. * val - The option's value
  102. *
  103. * Returned Value:
  104. * 0 on success, else a negative error code
  105. *
  106. ****************************************************************************/
  107. #define IOEXP_SETOPTION(dev,pin,opt,val) ((dev)->ops->ioe_option(dev,pin,opt,val))
  108. /****************************************************************************
  109. * Name: IOEXP_WRITEPIN
  110. *
  111. * Description:
  112. * Set the pin level. Required.
  113. *
  114. * Input Parameters:
  115. * dev - Device-specific state data
  116. * pin - The index of the pin to alter in this call
  117. * val - The pin level. Usually TRUE will set the pin high,
  118. * except if OPTION_INVERT has been set on this pin.
  119. *
  120. * Returned Value:
  121. * 0 on success, else a negative error code
  122. *
  123. ****************************************************************************/
  124. #define IOEXP_WRITEPIN(dev,pin,val) ((dev)->ops->ioe_writepin(dev,pin,val))
  125. /****************************************************************************
  126. * Name: IOEXP_READPIN
  127. *
  128. * Description:
  129. * Read the actual PIN level. This can be different from the last value
  130. * written to this pin. Required.
  131. *
  132. * Input Parameters:
  133. * dev - Device-specific state data
  134. * pin - The index of the pin
  135. * valptr - Pointer to a buffer where the pin level is stored. Usually TRUE
  136. * if the pin is high, except if OPTION_INVERT has been set on
  137. * this pin.
  138. *
  139. * Returned Value:
  140. * 0 on success, else a negative error code
  141. *
  142. ****************************************************************************/
  143. #define IOEXP_READPIN(dev,pin,valptr) ((dev)->ops->ioe_readpin(dev,pin,valptr))
  144. /****************************************************************************
  145. * Name: IOEXP_READBUF
  146. *
  147. * Description:
  148. * Read the buffered pin level.
  149. * This can be different from the actual pin state. Required.
  150. *
  151. * Input Parameters:
  152. * dev - Device-specific state data
  153. * pin - The index of the pin
  154. * valptr - Pointer to a buffer where the level is stored.
  155. *
  156. * Returned Value:
  157. * 0 on success, else a negative error code
  158. *
  159. ****************************************************************************/
  160. #define IOEXP_READBUF(dev,pin,valptr) ((dev)->ops->ioe_readbuf(dev,pin,valptr))
  161. #ifdef CONFIG_IOEXPANDER_MULTIPIN
  162. /****************************************************************************
  163. * Name: IOEXP_MULTIWRITEPIN
  164. *
  165. * Description:
  166. * Set the pin level for multiple pins. This routine may be faster than
  167. * individual pin accesses. Optional.
  168. *
  169. * Input Parameters:
  170. * dev - Device-specific state data
  171. * pins - The list of pin indexes to alter in this call
  172. * val - The list of pin levels.
  173. *
  174. * Returned Value:
  175. * 0 on success, else a negative error code
  176. *
  177. ****************************************************************************/
  178. #define IOEXP_MULTIWRITEPIN(dev,pins,vals,count) \
  179. ((dev)->ops->ioe_multiwritepin(dev,pins,vals,count))
  180. /****************************************************************************
  181. * Name: IOEXP_MULTIREADPIN
  182. *
  183. * Description:
  184. * Read the actual level for multiple pins. This routine may be faster than
  185. * individual pin accesses. Optional.
  186. *
  187. * Input Parameters:
  188. * dev - Device-specific state data
  189. * pin - The list of pin indexes to read
  190. * valptr - Pointer to a buffer where the pin levels are stored.
  191. *
  192. * Returned Value:
  193. * 0 on success, else a negative error code
  194. *
  195. ****************************************************************************/
  196. #define IOEXP_MULTIREADPIN(dev,pins,vals,count) \
  197. ((dev)->ops->ioe_multireadpin(dev,pins,vals,count))
  198. /****************************************************************************
  199. * Name: IOEXP_MULTIREADBUF
  200. *
  201. * Description:
  202. * Read the buffered level of multiple pins. This routine may be faster
  203. * than individual pin accesses. Optional.
  204. *
  205. * Input Parameters:
  206. * dev - Device-specific state data
  207. * pin - The index of the pin
  208. * valptr - Pointer to a buffer where the buffered levels are stored.
  209. *
  210. * Returned Value:
  211. * 0 on success, else a negative error code
  212. *
  213. ****************************************************************************/
  214. #define IOEXP_MULTIREADBUF(dev,pins,vals,count) \
  215. ((dev)->ops->ioe_multireadbuf(dev,pins,vals,count))
  216. #endif /* CONFIG_IOEXPANDER_MULTIPIN */
  217. /****************************************************************************
  218. * Name: IOEP_ATTACH
  219. *
  220. * Description:
  221. * Attach and enable a pin interrupt callback function.
  222. *
  223. * Input Parameters:
  224. * dev - Device-specific state data
  225. * pinset - The set of pin events that will generate the callback
  226. * callback - The pointer to callback function. NULL will detach the
  227. * callback.
  228. * arg - User-provided callback argument
  229. *
  230. * Returned Value:
  231. * A non-NULL handle value is returned on success. This handle may be
  232. * used later to detach and disable the pin interrupt.
  233. *
  234. ****************************************************************************/
  235. #ifdef CONFIG_IOEXPANDER_INT_ENABLE
  236. #define IOEP_ATTACH(dev,pinset,callback,arg) \
  237. ((dev)->ops->ioe_attach(dev,pinset,callback,arg))
  238. #endif
  239. /****************************************************************************
  240. * Name: IOEP_DETACH
  241. *
  242. * Description:
  243. * Detach and disable a pin interrupt callback function.
  244. *
  245. * Input Parameters:
  246. * dev - Device-specific state data
  247. * handle - The non-NULL opaque value return by IOEP_ATTACH
  248. *
  249. * Returned Value:
  250. * 0 on success, else a negative error code
  251. *
  252. ****************************************************************************/
  253. #ifdef CONFIG_IOEXPANDER_INT_ENABLE
  254. #define IOEP_DETACH(dev,handle) ((dev)->ops->ioe_detach(dev,handle))
  255. #endif
  256. /****************************************************************************
  257. * Public Types
  258. ****************************************************************************/
  259. /* This type represents a bitmap of pins
  260. *
  261. * For IOE NPINS greater than 64, ioe_pinset_t represent one interrupt pin
  262. * number instead of a bitmap of pins.
  263. */
  264. #if CONFIG_IOEXPANDER_NPINS <= 8
  265. typedef uint8_t ioe_pinset_t;
  266. #elif CONFIG_IOEXPANDER_NPINS <= 16
  267. typedef uint16_t ioe_pinset_t;
  268. #elif CONFIG_IOEXPANDER_NPINS <= 32
  269. typedef uint32_t ioe_pinset_t;
  270. #elif CONFIG_IOEXPANDER_NPINS <= 64
  271. typedef uint64_t ioe_pinset_t;
  272. #else
  273. typedef uint8_t ioe_pinset_t;
  274. #endif
  275. #ifdef CONFIG_IOEXPANDER_INT_ENABLE
  276. /* This type represents a pin interrupt callback function */
  277. struct ioexpander_dev_s;
  278. typedef CODE int (*ioe_callback_t)(FAR struct ioexpander_dev_s *dev,
  279. ioe_pinset_t pinset, FAR void *arg);
  280. #endif /* CONFIG_IOEXPANDER_INT_ENABLE */
  281. /* I/O expander interface methods */
  282. struct ioexpander_dev_s;
  283. struct ioexpander_ops_s
  284. {
  285. CODE int (*ioe_direction)(FAR struct ioexpander_dev_s *dev, uint8_t pin,
  286. int direction);
  287. CODE int (*ioe_option)(FAR struct ioexpander_dev_s *dev, uint8_t pin,
  288. int opt, FAR void *val);
  289. CODE int (*ioe_writepin)(FAR struct ioexpander_dev_s *dev, uint8_t pin,
  290. bool value);
  291. CODE int (*ioe_readpin)(FAR struct ioexpander_dev_s *dev, uint8_t pin,
  292. FAR bool *value);
  293. CODE int (*ioe_readbuf)(FAR struct ioexpander_dev_s *dev, uint8_t pin,
  294. FAR bool *value);
  295. #ifdef CONFIG_IOEXPANDER_MULTIPIN
  296. CODE int (*ioe_multiwritepin)(FAR struct ioexpander_dev_s *dev,
  297. FAR uint8_t *pins, FAR bool *values,
  298. int count);
  299. CODE int (*ioe_multireadpin)(FAR struct ioexpander_dev_s *dev,
  300. FAR uint8_t *pins, FAR bool *values,
  301. int count);
  302. CODE int (*ioe_multireadbuf)(FAR struct ioexpander_dev_s *dev,
  303. FAR uint8_t *pins, FAR bool *values,
  304. int count);
  305. #endif
  306. #ifdef CONFIG_IOEXPANDER_INT_ENABLE
  307. CODE FAR void *(*ioe_attach)(FAR struct ioexpander_dev_s *dev,
  308. ioe_pinset_t pinset,
  309. ioe_callback_t callback, FAR void *arg);
  310. CODE int (*ioe_detach)(FAR struct ioexpander_dev_s *dev,
  311. FAR void *handle);
  312. #endif
  313. };
  314. struct ioexpander_dev_s
  315. {
  316. /* "Lower half" operations provided by the I/O expander lower half */
  317. FAR const struct ioexpander_ops_s *ops;
  318. /* Internal storage used by the I/O expander may (internal to the I/O
  319. * expander implementation).
  320. */
  321. };
  322. #endif /* CONFIG_IOEXPANDER */
  323. #endif /* __INCLUDE_NUTTX_IOEXPANDER_IOEXPANDER_H */