chiark / gitweb /
4d07abcbcb256b4b9099923bf671d949726fc267
[wiringPi.git] / wiringPi / mcp3422.c
1 /*
2  * mcp3422.c:
3  *      Extend wiringPi with the MCP3422 I2C ADC chip
4  *      Also works for the MCP3423 and MCP3224 (4 channel) chips
5  *      Copyright (c) 2013 Gordon Henderson
6  ***********************************************************************
7  * This file is part of wiringPi:
8  *      https://projects.drogon.net/raspberry-pi/wiringpi/
9  *
10  *    wiringPi is free software: you can redistribute it and/or modify
11  *    it under the terms of the GNU Lesser General Public License as
12  *    published by the Free Software Foundation, either version 3 of the
13  *    License, or (at your option) any later version.
14  *
15  *    wiringPi is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU Lesser General Public License for more details.
19  *
20  *    You should have received a copy of the GNU Lesser General Public
21  *    License along with wiringPi.
22  *    If not, see <http://www.gnu.org/licenses/>.
23  ***********************************************************************
24  */
25
26
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31 #include <linux/spi/spidev.h>
32
33 #include <wiringPi.h>
34 #include <wiringPiI2C.h>
35
36 #include "mcp3422.h"
37
38
39 /*
40  * myAnalogRead:
41  *      Read a channel from the device
42  *********************************************************************************
43  */
44
45 int myAnalogRead (struct wiringPiNodeStruct *node, int chan)
46 {
47   unsigned char config, b0, b1, b2, b3 ;
48   int value = 0 ;
49
50 // One-shot mode, trigger plus the other configs.
51
52   config = 0x80 | ((chan - node->pinBase) << 5) | (node->data0 << 2) | (node->data1) ;
53   
54   wiringPiI2CWrite (node->fd, config) ;
55
56   switch (node->data0)  // Sample rate
57   {
58     case MCP3422_SR_3_75:                       // 18 bits
59       delay (270) ;
60       b0 = wiringPiI2CRead (node->fd) ;
61       b1 = wiringPiI2CRead (node->fd) ;
62       b2 = wiringPiI2CRead (node->fd) ;
63       b3 = wiringPiI2CRead (node->fd) ;
64       value = ((b0 & 3) << 16) | (b1 << 8) | b2 ;
65       break ;
66
67     case MCP3422_SR_15:                         // 16 bits
68       delay ( 70) ;
69       b0 = wiringPiI2CRead (node->fd) ;
70       b1 = wiringPiI2CRead (node->fd) ;
71       b2 = wiringPiI2CRead (node->fd) ;
72       value = (b0 << 8) | b1 ;
73       break ;
74
75     case MCP3422_SR_60:                         // 14 bits
76       delay ( 17) ;
77       b0 = wiringPiI2CRead (node->fd) ;
78       b1 = wiringPiI2CRead (node->fd) ;
79       b2 = wiringPiI2CRead (node->fd) ;
80       value = ((b0 & 0x3F) << 8) | b1 ;
81       break ;
82
83     case MCP3422_SR_240:                        // 12 bits
84       delay (  5) ;
85       b0 = wiringPiI2CRead (node->fd) ;
86       b1 = wiringPiI2CRead (node->fd) ;
87       b2 = wiringPiI2CRead (node->fd) ;
88       value = ((b0 & 0x0F) << 8) | b1 ;
89       break ;
90   }
91
92   return value ;
93 }
94
95
96 /*
97  * mcp3422Setup:
98  *      Create a new wiringPi device node for the mcp3422
99  *********************************************************************************
100  */
101
102 int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain)
103 {
104   int fd ;
105   struct wiringPiNodeStruct *node ;
106
107   if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
108     return fd ;
109
110   node = wiringPiNewNode (pinBase, 4) ;
111
112   node->data0      = sampleRate ;
113   node->data1      = gain ;
114   node->analogRead = myAnalogRead ;
115
116   return 0 ;
117 }