You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 6 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. /*
  2. * extensions.c:
  3. * Originally part of the GPIO program to test, peek, poke and otherwise
  4. * noodle with the GPIO hardware on the Raspberry Pi.
  5. * Now used as a general purpose library to allow systems to dynamically
  6. * add in new devices into wiringPi at program run-time.
  7. * Copyright (c) 2012-2015 Gordon Henderson
  8. ***********************************************************************
  9. * This file is part of wiringPi:
  10. * https://github.com/WiringPi/WiringPi/
  11. *
  12. * wiringPi is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Lesser General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * wiringPi is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public License
  23. * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
  24. ***********************************************************************
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <stdint.h>
  29. #include <stdarg.h>
  30. #include <ctype.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #include <errno.h>
  34. #include <sys/types.h>
  35. #include <fcntl.h>
  36. #include <wiringPi.h>
  37. #include "mcp23008.h"
  38. #include "mcp23016.h"
  39. #include "mcp23017.h"
  40. #include "mcp23s08.h"
  41. #include "mcp23s17.h"
  42. #include "sr595.h"
  43. #include "pcf8574.h"
  44. #include "pcf8591.h"
  45. #include "mcp3002.h"
  46. #include "mcp3004.h"
  47. #include "mcp4802.h"
  48. #include "mcp3422.h"
  49. #include "max31855.h"
  50. #include "max5322.h"
  51. #include "ads1115.h"
  52. #include "sn3218.h"
  53. #include "drcSerial.h"
  54. #include "drcNet.h"
  55. #include "../wiringPiD/drcNetCmd.h"
  56. #include "pseudoPins.h"
  57. #include "bmp180.h"
  58. #include "htu21d.h"
  59. #include "ds18b20.h"
  60. #include "rht03.h"
  61. #include "wpiExtensions.h"
  62. extern int wiringPiDebug ;
  63. static int verbose ;
  64. static char errorMessage [1024] ;
  65. // Local structure to hold details
  66. struct extensionFunctionStruct
  67. {
  68. const char *name ;
  69. int (*function)(char *progName, int pinBase, char *params) ;
  70. } ;
  71. /*
  72. * verbError:
  73. * Convenient error handling
  74. *********************************************************************************
  75. */
  76. static void verbError (const char *message, ...)
  77. {
  78. va_list argp ;
  79. va_start (argp, message) ;
  80. vsnprintf (errorMessage, 1023, message, argp) ;
  81. va_end (argp) ;
  82. if (verbose)
  83. fprintf (stderr, "%s\n", errorMessage) ;
  84. }
  85. /*
  86. * extractInt:
  87. * Check & return an integer at the given location (prefixed by a :)
  88. *********************************************************************************
  89. */
  90. static char *extractInt (char *progName, char *p, int *num)
  91. {
  92. if (*p != ':')
  93. {
  94. verbError ("%s: colon expected", progName) ;
  95. return NULL ;
  96. }
  97. ++p ;
  98. if (!isdigit (*p))
  99. {
  100. verbError ("%s: digit expected", progName) ;
  101. return NULL ;
  102. }
  103. *num = strtol (p, NULL, 0) ;
  104. // Increment p, but we need to check for hex 0x
  105. if ((*p == '0') && (*(p + 1) == 'x'))
  106. p +=2 ;
  107. while (isxdigit (*p))
  108. ++p ;
  109. return p ;
  110. }
  111. /*
  112. * extractStr:
  113. * Check & return a string at the given location (prefixed by a :)
  114. * Note: The string can be enclosed in []'s to escape colons. This is
  115. * so we can handle IPv6 addresses which contain colons and the []'s is
  116. * a common way to prepresent them.
  117. *********************************************************************************
  118. */
  119. static char *extractStr (char *progName, char *p, char **str)
  120. {
  121. char *q, *r ;
  122. int quoted = FALSE ;
  123. if (*p != ':')
  124. {
  125. verbError ("%s: colon expected", progName) ;
  126. return NULL ;
  127. }
  128. ++p ;
  129. if (*p == '[')
  130. {
  131. quoted = TRUE ;
  132. ++p ;
  133. }
  134. if (!isprint (*p)) // Is this needed?
  135. {
  136. verbError ("%s: character expected", progName) ;
  137. return NULL ;
  138. }
  139. q = p ;
  140. if (quoted)
  141. {
  142. while ((*q != 0) && (*q != ']'))
  143. ++q ;
  144. }
  145. else
  146. {
  147. while ((*q != 0) && (*q != ':'))
  148. ++q ;
  149. }
  150. *str = r = calloc (q - p + 2, 1) ; // Zeros it
  151. while (p != q)
  152. *r++ = *p++ ;
  153. if (quoted) // Skip over the ] to the :
  154. ++p ;
  155. return p ;
  156. }
  157. /*
  158. * doExtensionMcp23008:
  159. * MCP23008 - 8-bit I2C GPIO expansion chip
  160. * mcp23002:base:i2cAddr
  161. *********************************************************************************
  162. */
  163. static int doExtensionMcp23008 (char *progName, int pinBase, char *params)
  164. {
  165. int i2c ;
  166. if ((params = extractInt (progName, params, &i2c)) == NULL)
  167. return FALSE ;
  168. if ((i2c < 0x01) || (i2c > 0x77))
  169. {
  170. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  171. return FALSE ;
  172. }
  173. mcp23008Setup (pinBase, i2c) ;
  174. return TRUE ;
  175. }
  176. /*
  177. * doExtensionMcp23016:
  178. * MCP230016- 16-bit I2C GPIO expansion chip
  179. * mcp23016:base:i2cAddr
  180. *********************************************************************************
  181. */
  182. static int doExtensionMcp23016 (char *progName, int pinBase, char *params)
  183. {
  184. int i2c ;
  185. if ((params = extractInt (progName, params, &i2c)) == NULL)
  186. return FALSE ;
  187. if ((i2c < 0x03) || (i2c > 0x77))
  188. {
  189. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  190. return FALSE ;
  191. }
  192. mcp23016Setup (pinBase, i2c) ;
  193. return TRUE ;
  194. }
  195. /*
  196. * doExtensionMcp23017:
  197. * MCP230017- 16-bit I2C GPIO expansion chip
  198. * mcp23017:base:i2cAddr
  199. *********************************************************************************
  200. */
  201. static int doExtensionMcp23017 (char *progName, int pinBase, char *params)
  202. {
  203. int i2c ;
  204. if ((params = extractInt (progName, params, &i2c)) == NULL)
  205. return FALSE ;
  206. if ((i2c < 0x03) || (i2c > 0x77))
  207. {
  208. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  209. return FALSE ;
  210. }
  211. mcp23017Setup (pinBase, i2c) ;
  212. return TRUE ;
  213. }
  214. /*
  215. * doExtensionMcp23s08:
  216. * MCP23s08 - 8-bit SPI GPIO expansion chip
  217. * mcp23s08:base:spi:port
  218. *********************************************************************************
  219. */
  220. static int doExtensionMcp23s08 (char *progName, int pinBase, char *params)
  221. {
  222. int spi, port ;
  223. if ((params = extractInt (progName, params, &spi)) == NULL)
  224. return FALSE ;
  225. if ((spi < 0) || (spi > 1))
  226. {
  227. verbError ("%s: SPI address (%d) out of range", progName, spi) ;
  228. return FALSE ;
  229. }
  230. if ((params = extractInt (progName, params, &port)) == NULL)
  231. return FALSE ;
  232. if ((port < 0) || (port > 7))
  233. {
  234. verbError ("%s: port address (%d) out of range", progName, port) ;
  235. return FALSE ;
  236. }
  237. mcp23s08Setup (pinBase, spi, port) ;
  238. return TRUE ;
  239. }
  240. /*
  241. * doExtensionMcp23s17:
  242. * MCP23s17 - 16-bit SPI GPIO expansion chip
  243. * mcp23s17:base:spi:port
  244. *********************************************************************************
  245. */
  246. static int doExtensionMcp23s17 (char *progName, int pinBase, char *params)
  247. {
  248. int spi, port ;
  249. if ((params = extractInt (progName, params, &spi)) == NULL)
  250. return FALSE ;
  251. if ((spi < 0) || (spi > 1))
  252. {
  253. verbError ("%s: SPI address (%d) out of range", progName, spi) ;
  254. return FALSE ;
  255. }
  256. if ((params = extractInt (progName, params, &port)) == NULL)
  257. return FALSE ;
  258. if ((port < 0) || (port > 7))
  259. {
  260. verbError ("%s: port address (%d) out of range", progName, port) ;
  261. return FALSE ;
  262. }
  263. mcp23s17Setup (pinBase, spi, port) ;
  264. return TRUE ;
  265. }
  266. /*
  267. * doExtensionSr595:
  268. * Shift Register 74x595
  269. * sr595:base:pins:data:clock:latch
  270. *********************************************************************************
  271. */
  272. static int doExtensionSr595 (char *progName, int pinBase, char *params)
  273. {
  274. int pins, data, clock, latch ;
  275. // Extract pins
  276. if ((params = extractInt (progName, params, &pins)) == NULL)
  277. return FALSE ;
  278. if ((pins < 8) || (pins > 32))
  279. {
  280. verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ;
  281. return FALSE ;
  282. }
  283. if ((params = extractInt (progName, params, &data)) == NULL)
  284. return FALSE ;
  285. if ((params = extractInt (progName, params, &clock)) == NULL)
  286. return FALSE ;
  287. if ((params = extractInt (progName, params, &latch)) == NULL)
  288. return FALSE ;
  289. sr595Setup (pinBase, pins, data, clock, latch) ;
  290. return TRUE ;
  291. }
  292. /*
  293. * doExtensionPcf8574:
  294. * Digital IO (Crude!)
  295. * pcf8574:base:i2cAddr
  296. *********************************************************************************
  297. */
  298. static int doExtensionPcf8574 (char *progName, int pinBase, char *params)
  299. {
  300. int i2c ;
  301. if ((params = extractInt (progName, params, &i2c)) == NULL)
  302. return FALSE ;
  303. if ((i2c < 0x03) || (i2c > 0x77))
  304. {
  305. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  306. return FALSE ;
  307. }
  308. pcf8574Setup (pinBase, i2c) ;
  309. return TRUE ;
  310. }
  311. /*
  312. * doExtensionAds1115:
  313. * Analog Input
  314. * ads1115:base:i2cAddr
  315. *********************************************************************************
  316. */
  317. static int doExtensionAds1115 (char *progName, int pinBase, char *params)
  318. {
  319. int i2c ;
  320. if ((params = extractInt (progName, params, &i2c)) == NULL)
  321. return FALSE ;
  322. if ((i2c < 0x03) || (i2c > 0x77))
  323. {
  324. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  325. return FALSE ;
  326. }
  327. ads1115Setup (pinBase, i2c) ;
  328. return TRUE ;
  329. }
  330. /*
  331. * doExtensionPcf8591:
  332. * Analog IO
  333. * pcf8591:base:i2cAddr
  334. *********************************************************************************
  335. */
  336. static int doExtensionPcf8591 (char *progName, int pinBase, char *params)
  337. {
  338. int i2c ;
  339. if ((params = extractInt (progName, params, &i2c)) == NULL)
  340. return FALSE ;
  341. if ((i2c < 0x03) || (i2c > 0x77))
  342. {
  343. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  344. return FALSE ;
  345. }
  346. pcf8591Setup (pinBase, i2c) ;
  347. return TRUE ;
  348. }
  349. /*
  350. * doExtensionPseudoPins:
  351. * 64 Memory resident pseudo pins
  352. * pseudoPins:base
  353. *********************************************************************************
  354. */
  355. static int doExtensionPseudoPins (UNU char *progName, int pinBase, UNU char *params)
  356. {
  357. pseudoPinsSetup (pinBase) ;
  358. return TRUE ;
  359. }
  360. /*
  361. * doExtensionBmp180:
  362. * Analog Temp + Pressure
  363. * bmp180:base
  364. *********************************************************************************
  365. */
  366. static int doExtensionBmp180 (UNU char *progName, int pinBase, UNU char *params)
  367. {
  368. bmp180Setup (pinBase) ;
  369. return TRUE ;
  370. }
  371. /*
  372. * doExtensionHtu21d:
  373. * Analog humidity + Pressure
  374. * htu21d:base
  375. *********************************************************************************
  376. */
  377. static int doExtensionHtu21d (UNU char *progName, int pinBase, UNU char *params)
  378. {
  379. htu21dSetup (pinBase) ;
  380. return TRUE ;
  381. }
  382. /*
  383. * doExtensionDs18b20:
  384. * 1-Wire Temperature
  385. * htu21d:base:serialNum
  386. *********************************************************************************
  387. */
  388. static int doExtensionDs18b20 (char *progName, int pinBase, char *params)
  389. {
  390. char *serialNum ;
  391. if ((params = extractStr (progName, params, &serialNum)) == NULL)
  392. return FALSE ;
  393. return ds18b20Setup (pinBase, serialNum) ;
  394. }
  395. /*
  396. * doExtensionRht03:
  397. * Maxdetect 1-Wire Temperature & Humidity
  398. * rht03:base:piPin
  399. *********************************************************************************
  400. */
  401. static int doExtensionRht03 (char *progName, int pinBase, char *params)
  402. {
  403. int piPin ;
  404. if ((params = extractInt (progName, params, &piPin)) == NULL)
  405. return FALSE ;
  406. return rht03Setup (pinBase, piPin) ;
  407. }
  408. /*
  409. * doExtensionMax31855:
  410. * Analog IO
  411. * max31855:base:spiChan
  412. *********************************************************************************
  413. */
  414. static int doExtensionMax31855 (char *progName, int pinBase, char *params)
  415. {
  416. int spi ;
  417. if ((params = extractInt (progName, params, &spi)) == NULL)
  418. return FALSE ;
  419. if ((spi < 0) || (spi > 1))
  420. {
  421. verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
  422. return FALSE ;
  423. }
  424. max31855Setup (pinBase, spi) ;
  425. return TRUE ;
  426. }
  427. /*
  428. * doExtensionMcp3002:
  429. * Analog IO
  430. * mcp3002:base:spiChan
  431. *********************************************************************************
  432. */
  433. static int doExtensionMcp3002 (char *progName, int pinBase, char *params)
  434. {
  435. int spi ;
  436. if ((params = extractInt (progName, params, &spi)) == NULL)
  437. return FALSE ;
  438. if ((spi < 0) || (spi > 1))
  439. {
  440. verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
  441. return FALSE ;
  442. }
  443. mcp3002Setup (pinBase, spi) ;
  444. return TRUE ;
  445. }
  446. /*
  447. * doExtensionMcp3004:
  448. * Analog IO
  449. * mcp3004:base:spiChan
  450. *********************************************************************************
  451. */
  452. static int doExtensionMcp3004 (char *progName, int pinBase, char *params)
  453. {
  454. int spi ;
  455. if ((params = extractInt (progName, params, &spi)) == NULL)
  456. return FALSE ;
  457. if ((spi < 0) || (spi > 1))
  458. {
  459. verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
  460. return FALSE ;
  461. }
  462. mcp3004Setup (pinBase, spi) ;
  463. return TRUE ;
  464. }
  465. /*
  466. * doExtensionMax5322:
  467. * Analog O
  468. * max5322:base:spiChan
  469. *********************************************************************************
  470. */
  471. static int doExtensionMax5322 (char *progName, int pinBase, char *params)
  472. {
  473. int spi ;
  474. if ((params = extractInt (progName, params, &spi)) == NULL)
  475. return FALSE ;
  476. if ((spi < 0) || (spi > 1))
  477. {
  478. verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
  479. return FALSE ;
  480. }
  481. max5322Setup (pinBase, spi) ;
  482. return TRUE ;
  483. }
  484. /*
  485. * doExtensionMcp4802:
  486. * Analog IO
  487. * mcp4802:base:spiChan
  488. *********************************************************************************
  489. */
  490. static int doExtensionMcp4802 (char *progName, int pinBase, char *params)
  491. {
  492. int spi ;
  493. if ((params = extractInt (progName, params, &spi)) == NULL)
  494. return FALSE ;
  495. if ((spi < 0) || (spi > 1))
  496. {
  497. verbError ("%s: SPI channel (%d) out of range", progName, spi) ;
  498. return FALSE ;
  499. }
  500. mcp4802Setup (pinBase, spi) ;
  501. return TRUE ;
  502. }
  503. /*
  504. * doExtensionSn3218:
  505. * Analog Output (LED Driver)
  506. * sn3218:base
  507. *********************************************************************************
  508. */
  509. static int doExtensionSn3218 (UNU char *progName, int pinBase, UNU char *params)
  510. {
  511. sn3218Setup (pinBase) ;
  512. return TRUE ;
  513. }
  514. /*
  515. * doExtensionMcp3422:
  516. * Analog IO
  517. * mcp3422:base:i2cAddr
  518. *********************************************************************************
  519. */
  520. static int doExtensionMcp3422 (char *progName, int pinBase, char *params)
  521. {
  522. int i2c, sampleRate, gain ;
  523. if ((params = extractInt (progName, params, &i2c)) == NULL)
  524. return FALSE ;
  525. if ((i2c < 0x03) || (i2c > 0x77))
  526. {
  527. verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ;
  528. return FALSE ;
  529. }
  530. if ((params = extractInt (progName, params, &sampleRate)) == NULL)
  531. return FALSE ;
  532. if ((sampleRate < 0) || (sampleRate > 3))
  533. {
  534. verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ;
  535. return FALSE ;
  536. }
  537. if ((params = extractInt (progName, params, &gain)) == NULL)
  538. return FALSE ;
  539. if ((gain < 0) || (gain > 3))
  540. {
  541. verbError ("%s: gain (%d) out of range", progName, gain) ;
  542. return FALSE ;
  543. }
  544. mcp3422Setup (pinBase, i2c, sampleRate, gain) ;
  545. return TRUE ;
  546. }
  547. /*
  548. * doExtensionDrcS:
  549. * Interface to a DRC Serial system
  550. * drcs:base:pins:serialPort:baud
  551. *********************************************************************************
  552. */
  553. static int doExtensionDrcS (char *progName, int pinBase, char *params)
  554. {
  555. char *port ;
  556. int pins, baud ;
  557. if ((params = extractInt (progName, params, &pins)) == NULL)
  558. return FALSE ;
  559. if ((pins < 1) || (pins > 1000))
  560. {
  561. verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
  562. return FALSE ;
  563. }
  564. if ((params = extractStr (progName, params, &port)) == NULL)
  565. return FALSE ;
  566. if (strlen (port) == 0)
  567. {
  568. verbError ("%s: serial port device name required", progName) ;
  569. return FALSE ;
  570. }
  571. if ((params = extractInt (progName, params, &baud)) == NULL)
  572. return FALSE ;
  573. if ((baud < 1) || (baud > 4000000))
  574. {
  575. verbError ("%s: baud rate (%d) out of range", progName, baud) ;
  576. return FALSE ;
  577. }
  578. drcSetupSerial (pinBase, pins, port, baud) ;
  579. return TRUE ;
  580. }
  581. /*
  582. * doExtensionDrcNet:
  583. * Interface to a DRC Network system
  584. * drcn:base:pins:ipAddress:port:password
  585. *********************************************************************************
  586. */
  587. static int doExtensionDrcNet (char *progName, int pinBase, char *params)
  588. {
  589. int pins ;
  590. char *ipAddress, *port, *password ;
  591. char pPort [1024] ;
  592. if ((params = extractInt (progName, params, &pins)) == NULL)
  593. return FALSE ;
  594. if ((pins < 1) || (pins > 1000))
  595. {
  596. verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ;
  597. return FALSE ;
  598. }
  599. if ((params = extractStr (progName, params, &ipAddress)) == NULL)
  600. return FALSE ;
  601. if (strlen (ipAddress) == 0)
  602. {
  603. verbError ("%s: ipAddress required", progName) ;
  604. return FALSE ;
  605. }
  606. if ((params = extractStr (progName, params, &port)) == NULL)
  607. return FALSE ;
  608. if (strlen (port) == 0)
  609. {
  610. sprintf (pPort, "%d", DEFAULT_SERVER_PORT) ;
  611. port = pPort ;
  612. }
  613. if ((params = extractStr (progName, params, &password)) == NULL)
  614. return FALSE ;
  615. if (strlen (password) == 0)
  616. {
  617. verbError ("%s: password required", progName) ;
  618. return FALSE ;
  619. }
  620. return drcSetupNet (pinBase, pins, ipAddress, port, password) ;
  621. }
  622. /*
  623. * Function list
  624. *********************************************************************************
  625. */
  626. static struct extensionFunctionStruct extensionFunctions [] =
  627. {
  628. { "mcp23008", &doExtensionMcp23008 },
  629. { "mcp23016", &doExtensionMcp23016 },
  630. { "mcp23017", &doExtensionMcp23017 },
  631. { "mcp23s08", &doExtensionMcp23s08 },
  632. { "mcp23s17", &doExtensionMcp23s17 },
  633. { "sr595", &doExtensionSr595 },
  634. { "pcf8574", &doExtensionPcf8574 },
  635. { "pcf8591", &doExtensionPcf8591 },
  636. { "bmp180", &doExtensionBmp180 },
  637. { "pseudoPins", &doExtensionPseudoPins },
  638. { "htu21d", &doExtensionHtu21d },
  639. { "ds18b20", &doExtensionDs18b20 },
  640. { "rht03", &doExtensionRht03 },
  641. { "mcp3002", &doExtensionMcp3002 },
  642. { "mcp3004", &doExtensionMcp3004 },
  643. { "mcp4802", &doExtensionMcp4802 },
  644. { "mcp3422", &doExtensionMcp3422 },
  645. { "max31855", &doExtensionMax31855 },
  646. { "ads1115", &doExtensionAds1115 },
  647. { "max5322", &doExtensionMax5322 },
  648. { "sn3218", &doExtensionSn3218 },
  649. { "drcs", &doExtensionDrcS },
  650. { "drcn", &doExtensionDrcNet },
  651. { NULL, NULL },
  652. } ;
  653. /*
  654. * loadWPiExtension:
  655. * Load in a wiringPi extension
  656. * The extensionData always starts with the name, a colon then the pinBase
  657. * number. Other parameters after that are decoded by the module in question.
  658. *********************************************************************************
  659. */
  660. int loadWPiExtension (char *progName, char *extensionData, int printErrors)
  661. {
  662. char *p ;
  663. char *extension = extensionData ;
  664. struct extensionFunctionStruct *extensionFn ;
  665. int pinBase = 0 ;
  666. verbose = printErrors ;
  667. // Get the extension name by finding the first colon
  668. p = extension ;
  669. while (*p != ':')
  670. {
  671. if (!*p) // ran out of characters
  672. {
  673. verbError ("%s: extension name not terminated by a colon", progName) ;
  674. return FALSE ;
  675. }
  676. ++p ;
  677. }
  678. *p++ = 0 ;
  679. // Simple ATOI code
  680. if (!isdigit (*p))
  681. {
  682. verbError ("%s: decimal pinBase number expected after extension name", progName) ;
  683. return FALSE ;
  684. }
  685. while (isdigit (*p))
  686. {
  687. if (pinBase > 2147483647) // 2^31-1 ... Lets be realistic here...
  688. {
  689. verbError ("%s: pinBase too large", progName) ;
  690. return FALSE ;
  691. }
  692. pinBase = pinBase * 10 + (*p - '0') ;
  693. ++p ;
  694. }
  695. if (pinBase < 64)
  696. {
  697. verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ;
  698. return FALSE ;
  699. }
  700. // Search for extensions:
  701. for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn)
  702. {
  703. if (strcmp (extensionFn->name, extension) == 0)
  704. return extensionFn->function (progName, pinBase, p) ;
  705. }
  706. fprintf (stderr, "%s: extension %s not found", progName, extension) ;
  707. return FALSE ;
  708. }