chiark / gitweb /
Tidying up some old debug
[wiringPi.git] / wiringPi / 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 "gertboard.h"
42
43
44 // The SPI bus parameters
45 //      Variables as they need to be passed as pointers later on
46
47 static char       *spiA2D = "/dev/spidev0.0" ;
48 static char       *spiD2A = "/dev/spidev0.1" ;
49 static uint8_t     spiMode   = 0 ;
50 static uint8_t     spiBPW    = 8 ;
51 static uint32_t    spiSpeed  = 100000 ; // 1MHz
52 static uint16_t    spiDelay  = 0;
53
54 // Locals here to keep track of everything
55
56 static int spiFdA2D ;
57 static int spiFdD2A ;
58
59
60 /*
61  * gertboardAnalogWrite:
62  *      Write an 8-bit data value to the MCP4802 Analog to digital
63  *      convertor on the Gertboard.
64  *********************************************************************************
65  */
66
67 void gertboardAnalogWrite (int chan, int value)
68 {
69   uint8_t spiBufTx [2] ;
70   uint8_t spiBufRx [2] ;
71   struct spi_ioc_transfer spi ;
72
73   uint8_t chanBits, dataBits ;
74
75   if (chan == 0)
76     chanBits = 0x30 ;
77   else
78     chanBits = 0xB0 ;
79
80   chanBits |= ((value >> 4) & 0x0F) ;
81   dataBits  = ((value << 4) & 0xF0) ;
82
83   spiBufTx [0] = chanBits ;
84   spiBufTx [1] = dataBits ;
85
86   spi.tx_buf        = (unsigned long)spiBufTx ;
87   spi.rx_buf        = (unsigned long)spiBufRx ;
88   spi.len           = 2 ;
89   spi.delay_usecs   = spiDelay ;
90   spi.speed_hz      = spiSpeed ;
91   spi.bits_per_word = spiBPW ;
92
93   ioctl (spiFdD2A, SPI_IOC_MESSAGE(1), &spi) ;
94 }
95
96
97 /*
98  * gertboardAnalogRead:
99  *      Return the analog value of the given channel (0/1).
100  *      The A/D is a 10-bit device
101  *********************************************************************************
102  */
103
104 int gertboardAnalogRead (int chan)
105 {
106   uint8_t spiBufTx [4] ;
107   uint8_t spiBufRx [4] ;
108   struct spi_ioc_transfer spi ;
109
110   uint8_t chanBits ;
111
112   if (chan == 0)
113     chanBits = 0b0110100 ;
114   else
115     chanBits = 0b0111100 ;
116
117   spiBufTx [0] = chanBits ;
118   spiBufTx [1] = 0 ;
119
120   spi.tx_buf        = (unsigned long)spiBufTx ;
121   spi.rx_buf        = (unsigned long)spiBufRx ;
122   spi.len           = 4 ;
123   spi.delay_usecs   = spiDelay ;
124   spi.speed_hz      = spiSpeed ;
125   spi.bits_per_word = spiBPW ;
126
127   ioctl (spiFdA2D, SPI_IOC_MESSAGE(1), &spi) ;
128
129   return spiBufRx [0] << 8 | spiBufRx [1] ;
130 }
131
132
133 /*
134  * setParams:
135  *      Output the SPI bus parameters to the given device
136  *********************************************************************************
137  */
138
139 static int setParams (int fd)
140 {
141   if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0)
142     return -1 ;
143
144   if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0)
145     return -1 ;
146
147   if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
148     return -1 ;
149
150   if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0)
151     return -1 ;
152
153   if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0)
154     return -1 ;
155
156   if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0)
157     return -1 ;
158
159   return 0 ;
160 }
161
162
163 /*
164  * gertboardSPISetup:
165  *      Initialise the SPI bus, etc.
166  *********************************************************************************
167  */
168
169 int gertboardSPISetup (void)
170 {
171   if ((spiFdA2D = open (spiA2D, O_RDWR)) < 0)
172     return -1 ;
173
174   if (setParams (spiFdA2D) != 0)
175     return -1 ;
176
177   if ((spiFdD2A = open (spiD2A, O_RDWR)) < 0)
178     return -1 ;
179
180   if (setParams (spiFdD2A) != 0)
181     return -1 ;
182
183   return 0 ;
184 }