Statistics
| Branch: | Revision:

ddr4s / fw / wiringPi / wiringPi / mcp3422.c @ 32:cadb9025f1e0

History | View | Annotate | Download (3.33 KB)

1
/*
2
 * mcp3422.c:
3
 *        Extend wiringPi with the MCP3422/3/4 I2C ADC chip
4
 *        This code assumes single-ended mode only.
5
 *        Tested on actual hardware: 20th Feb 2016.
6
 *        Copyright (c) 2013-2016 Gordon Henderson
7
 ***********************************************************************
8
 * This file is part of wiringPi:
9
 *        https://projects.drogon.net/raspberry-pi/wiringpi/
10
 *
11
 *    wiringPi is free software: you can redistribute it and/or modify
12
 *    it under the terms of the GNU Lesser General Public License as
13
 *    published by the Free Software Foundation, either version 3 of the
14
 *    License, or (at your option) any later version.
15
 *
16
 *    wiringPi is distributed in the hope that it will be useful,
17
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *    GNU Lesser General Public License for more details.
20
 *
21
 *    You should have received a copy of the GNU Lesser General Public
22
 *    License along with wiringPi.
23
 *    If not, see <http://www.gnu.org/licenses/>.
24
 ***********************************************************************
25
 */
26

    
27

    
28
#include <stdio.h>
29
#include <unistd.h>
30
#include <stdint.h>
31
#include <fcntl.h>
32
#include <sys/ioctl.h>
33

    
34
#include <wiringPi.h>
35
#include <wiringPiI2C.h>
36

    
37
#include "mcp3422.h"
38

    
39

    
40
/*
41
 * waitForConversion:
42
 *        Common code to wait for the ADC to finish conversion
43
 *********************************************************************************
44
 */
45

    
46
void waitForConversion (int fd, unsigned char *buffer, int n)
47
{
48
  for (;;)
49
  {
50
    read (fd, buffer, n) ;
51
    if ((buffer [n-1] & 0x80) == 0)
52
      break ;
53
    delay (1) ;
54
  }
55
}
56

    
57
/*
58
 * myAnalogRead:
59
 *        Read a channel from the device
60
 *********************************************************************************
61
 */
62

    
63
int myAnalogRead (struct wiringPiNodeStruct *node, int chan)
64
{
65
  unsigned char config ;
66
  unsigned char buffer [4] ;
67
  int value = 0 ;
68
  int realChan = (chan & 3) - node->pinBase ;
69

    
70
// One-shot mode, trigger plus the other configs.
71

    
72
  config = 0x80 | (realChan << 5) | (node->data0 << 2) | (node->data1) ;
73
  
74
  wiringPiI2CWrite (node->fd, config) ;
75

    
76
  switch (node->data0)        // Sample rate
77
  {
78
    case MCP3422_SR_3_75:                        // 18 bits
79
      waitForConversion (node->fd, &buffer [0], 4) ;
80
      value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [2] ;
81
      break ;
82

    
83
    case MCP3422_SR_15:                                // 16 bits
84
      waitForConversion (node->fd, buffer, 3) ;
85
      value = (buffer [0] << 8) | buffer [1] ;
86
      break ;
87

    
88
    case MCP3422_SR_60:                                // 14 bits
89
      waitForConversion (node->fd, buffer, 3) ;
90
      value = ((buffer [0] & 0x3F) << 8) | buffer [1] ;
91
      break ;
92

    
93
    case MCP3422_SR_240:                        // 12 bits - default
94
      waitForConversion (node->fd, buffer, 3) ;
95
      value = ((buffer [0] & 0x0F) << 8) | buffer [1] ;
96
      break ;
97
  }
98

    
99
  return value ;
100
}
101

    
102

    
103
/*
104
 * mcp3422Setup:
105
 *        Create a new wiringPi device node for the mcp3422
106
 *********************************************************************************
107
 */
108

    
109
int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain)
110
{
111
  int fd ;
112
  struct wiringPiNodeStruct *node ;
113

    
114
  if ((fd = wiringPiI2CSetup (i2cAddress)) < 0)
115
    return FALSE ;
116

    
117
  node = wiringPiNewNode (pinBase, 4) ;
118

    
119
  node->fd         = fd ;
120
  node->data0      = sampleRate ;
121
  node->data1      = gain ;
122
  node->analogRead = myAnalogRead ;
123

    
124
  return TRUE ;
125
}