chiark / gitweb /
Slight change to the gpio program to fix SPI buffer size when loading
[wiringPi.git] / devLib / gertboard.c
1 /*
2  * gertboard.c:
3  *      Access routines for the SPI devices on the Gertboard
4  *      Copyright (c) 2012 Gordon Henderson
5  *
6  *      The Gertboard has:
7  *
8  *              An MCP3002 dual-channel A to D convertor connected
9  *              to the SPI bus, selected by chip-select A, and:
10  *
11  *              An MCP4802 dual-channel D to A convertor connected
12  *              to the SPI bus, selected via chip-select B.
13  *
14  ***********************************************************************
15  * This file is part of wiringPi:
16  *      https://projects.drogon.net/raspberry-pi/wiringpi/
17  *
18  *    wiringPi is free software: you can redistribute it and/or modify
19  *    it under the terms of the GNU Lesser General Public License as
20  *    published by the Free Software Foundation, either version 3 of the
21  *    License, or (at your option) any later version.
22  *
23  *    wiringPi is distributed in the hope that it will be useful,
24  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *    GNU Lesser General Public License for more details.
27  *
28  *    You should have received a copy of the GNU Lesser General Public
29  *    License along with wiringPi.
30  *    If not, see <http://www.gnu.org/licenses/>.
31  ***********************************************************************
32  */
33
34
35 #include <stdio.h>
36 #include <stdint.h>
37 #include <fcntl.h>
38 #include <sys/ioctl.h>
39 #include <linux/spi/spidev.h>
40
41 #include <wiringPi.h>
42 #include <wiringPiSPI.h>
43
44 #include "gertboard.h"
45
46 // The A-D convertor won't run at more than 1MHz @ 3.3v
47
48 #define SPI_ADC_SPEED   1000000
49 #define SPI_DAC_SPEED   1000000
50 #define SPI_A2D               0
51 #define SPI_D2A               1
52
53
54 /*
55  * gertboardAnalogWrite:
56  *      Write an 8-bit data value to the MCP4802 Analog to digital
57  *      convertor on the Gertboard.
58  *********************************************************************************
59  */
60
61 void gertboardAnalogWrite (const int chan, const int value)
62 {
63   uint8_t spiData [2] ;
64   uint8_t chanBits, dataBits ;
65
66   if (chan == 0)
67     chanBits = 0x30 ;
68   else
69     chanBits = 0xB0 ;
70
71   chanBits |= ((value >> 4) & 0x0F) ;
72   dataBits  = ((value << 4) & 0xF0) ;
73
74   spiData [0] = chanBits ;
75   spiData [1] = dataBits ;
76
77   wiringPiSPIDataRW (SPI_D2A, spiData, 2) ;
78 }
79
80
81 /*
82  * gertboardAnalogRead:
83  *      Return the analog value of the given channel (0/1).
84  *      The A/D is a 10-bit device
85  *********************************************************************************
86  */
87
88 int gertboardAnalogRead (const int chan)
89 {
90   uint8_t spiData [2] ;
91
92   uint8_t chanBits ;
93
94   if (chan == 0)
95     chanBits = 0b11010000 ;
96   else
97     chanBits = 0b11110000 ;
98
99   spiData [0] = chanBits ;
100   spiData [1] = 0 ;
101
102   wiringPiSPIDataRW (SPI_A2D, spiData, 2) ;
103
104   return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ;
105 }
106
107
108 /*
109  * gertboardSPISetup:
110  *      Initialise the SPI bus, etc.
111  *********************************************************************************
112  */
113
114 int gertboardSPISetup (void)
115 {
116   if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0)
117     return -1 ;
118
119   if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0)
120     return -1 ;
121
122   return 0 ;
123 }
124
125
126 /*
127  * New wiringPi node extension methods.
128  *********************************************************************************
129  */
130
131 static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan)
132 {
133   return gertboardAnalogRead (chan - node->pinBase) ;
134 }
135
136 static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value)
137 {
138   gertboardAnalogWrite (chan - node->pinBase, value) ;
139 }
140
141
142 /*
143  * gertboardAnalogSetup:
144  *      Create a new wiringPi device node for the analog devices on the
145  *      Gertboard. We create one node with 2 pins - each pin being read
146  *      and write - although the operations actually go to different
147  *      hardware devices.
148  *********************************************************************************
149  */
150
151 int gertboardAnalogSetup (const int pinBase)
152 {
153   struct wiringPiNodeStruct *node ;
154   int    x ;
155
156   if (( x = gertboardSPISetup ()) != 0)
157     return  x;
158
159   node = wiringPiNewNode (pinBase, 2) ;
160   node->analogRead  = myAnalogRead ;
161   node->analogWrite = myAnalogWrite ;
162
163   return 0 ;
164 }