001package com.pi4j.wiringpi;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  Spi.java
009 *
010 * This file is part of the Pi4J project. More information about
011 * this project can be found here:  https://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2021 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032
033import com.pi4j.util.NativeLibraryLoader;
034
035/**
036 * <p>
037 * WiringPi includes a library which can make it easier to use the Raspberry Pi’s on-board SPI interface.
038 * </p>
039 *
040 * <p>
041 * Before you can use SPI interface, you may need to use the gpio utility to load the SPI drivers into the kernel:
042 *  > gpio load spi
043 *
044 * If you need a buffer size of greater than 4KB, then you can specify the size (in KB) on the command line:
045 *  > gpio load spi 100
046 *
047 * will allocate a 100KB buffer. (You should rarely need this though, the default is more than enough
048 * for most applications).
049 * </p>
050 *
051 * <p>
052 * <blockquote> This library depends on the wiringPi native system library.</br> (developed by
053 * Gordon Henderson @ <a href="http://wiringpi.com/">http://wiringpi.com</a>)
054 * </blockquote>
055 * </p>
056 *
057 * @see <a href="https.pi4j.com/">https://www.pi4j.com</a>
058 * @see <a
059 *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
060 * @author Robert Savage (<a
061 *         href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
062 */
063public class Spi {
064
065    public static int CHANNEL_0 = 0;
066    public static int CHANNEL_1 = 1;
067
068    public static int MODE_0 = 0;
069    public static int MODE_1 = 1;
070    public static int MODE_2 = 2;
071    public static int MODE_3 = 3;
072
073    // private constructor
074    private Spi()  {
075        // forbid object construction
076    }
077
078    static {
079        // Load the platform library
080        NativeLibraryLoader.load("libpi4j.so", "pi4j");
081    }
082
083    /**
084     * <p>wiringPiSPISetup:</p>
085     *
086     * <p>
087     * This is the way to initialise a channel (The Pi has 2 channels; 0 and 1). The speed parameter is an integer in
088     * the range 500,000 through 32,000,000 and represents the SPI clock speed in Hz.
089     * </p>
090     *
091     * <p>
092     * The returned value is the Linux file-descriptor for the device, or -1 on error. If an error has happened, you
093     * may use the standard errno global variable to see why.
094     * </p>
095     *
096     * @see <a
097     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
098     * @param channel SPI channel
099     * @param speed SPI speed
100     * @return return -1 on error
101     */
102    public static native int wiringPiSPISetup(int channel, int speed);
103
104
105    /**
106     * <p>wiringPiSPISetupMode:</p>
107     *
108     * <p>
109     * This is the way to initialise a channel (The Pi has 2 channels; 0 and 1). The speed parameter is an integer in
110     * the range 500,000 through 32,000,000 and represents the SPI clock speed in Hz.
111     * </p>
112     *
113     * <p>
114     * The returned value is the Linux file-descriptor for the device, or -1 on error. If an error has happened, you
115     * may use the standard errno global variable to see why.
116     * </p>
117     *
118     * @see <a
119     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
120     * @see <a
121     *      hfref="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers">http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers</a>
122     * @param channel SPI channel
123     * @param speed SPI speed
124     * @param mode SPI mode (Mode is 0, 1, 2 or 3; see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_numbers)
125     * @return return -1 on error
126     */
127    public static native int wiringPiSPISetupMode (int channel, int speed, int mode);
128
129    /**
130     * <p>wiringPiSPIGetFd:</p>
131     *
132     * <p>
133     * Return the file-descriptor for the given channel
134     * </p>
135     *
136     * @see <a
137     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
138     * @param channel SPI channel
139     * @return file-descriptor for the given channel
140     */
141    public static native int wiringPiSPIGetFd(int channel);
142
143    /**
144     * <p>wiringPiSPIDataRW:</p>
145     *
146     * <p>
147     * This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is
148     * overwritten by data returned from the SPI bus.
149     * </p>
150     *
151     * <p>
152     * (ATTENTION: the 'data' argument can only be a maximum of 1024 characters.)
153     * </p>
154     *
155     * @see <a
156     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
157     * @param channel SPI channel</p>
158     * @param data string data payload
159     * @return return -1 on error
160     */
161    public static int wiringPiSPIDataRW(int channel, String data){
162        return wiringPiSPIDataRW(channel, data, data.length());
163    }
164
165    /**
166     * <p>wiringPiSPIDataRW:</p>
167     *
168     * <p>
169     * This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is
170     * overwritten by data returned from the SPI bus.
171     * </p>
172     *
173     * <p>
174     * (ATTENTION: the 'data' argument can only be a maximum of 1024 characters.)
175     * </p>
176     *
177     * @see <a
178     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
179     * @param channel SPI channel</p>
180     * @param data string data payload
181     * @param len length of characters in string (must be total string length, not a substring)
182     * @return return -1 on error
183     */
184    public static native int wiringPiSPIDataRW(int channel, String data, int len);
185
186    /**
187     * <p>wiringPiSPIDataRW:</p>
188     *
189     * <p>
190     * This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is
191     * overwritten by data returned from the SPI bus.
192     * </p>
193     *
194     * <p>
195     * (ATTENTION: the 'data' argument can only be a maximum of 1024 characters.)
196     * </p>
197     *
198     * @see <a
199     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
200     * @param channel
201     *             SPI channel
202     * @param data
203     *             byte array data payload
204     * @param len
205     *             length of bytes in data array argument
206     * @return return -1 on error
207     */
208    public static native int wiringPiSPIDataRW(int channel, byte[] data, int len);
209
210
211    /**
212     * <p>wiringPiSPIDataRW:</p>
213     *
214     * <p>
215     * This performs a simultaneous write/read transaction over the selected SPI bus. Data that was in your buffer is
216     * overwritten by data returned from the SPI bus.
217     * </p>
218     *
219     * <p>
220     * (ATTENTION: the 'data' argument can only be a maximum of 1024 characters.)
221     * </p>
222     *
223     * @see <a
224     *      href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
225     * @param channel
226     *             SPI channel
227     * @param data
228     *             byte array data payload
229     * @return return -1 on error
230     */
231    public static int wiringPiSPIDataRW(int channel, byte[] data){
232        return wiringPiSPIDataRW(channel, data, data.length);
233    }
234
235    /**
236     * <p>
237     * wiringPiSPIDataRW:
238     * </p>
239     *
240     * <p>
241     * This performs a simultaneous write/read transaction over the selected SPI bus. The data argument is passed into the wiringPI function as the argument and the output from Spi is returned by this
242     * method
243     * </p>
244     *
245     * @see <a href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
246     * @param channel
247     *            SPI channel
248     * @param data
249     *            short array data payload. Note that wiringPi uses unsigned char for the data transmission. That is 8-bit. in other words values 0-255. So make sure the values in data do not exceed
250     *            this range, otherwise the numbers would overflow in the native code and unexpected results would yield
251     * @param len
252     *             length of bytes in data array argument
253     * @return return -1 on error
254     */
255    public static native int wiringPiSPIDataRW(int channel, short[] data, int len);
256
257    /**
258     * <p>
259     * wiringPiSPIDataRW:
260     * </p>
261     *
262     * <p>
263     * This performs a simultaneous write/read transaction over the selected SPI bus. The data argument is passed into the wiringPI function as the argument and the output from Spi is returned by this
264     * method
265     * </p>
266     *
267     * @see <a href="http://wiringpi.com/reference/spi-library/">http://wiringpi.com/reference/spi-library</a>
268     * @param channel
269     *            SPI channel
270     * @param data
271     *            short array data payload. Note that wiringPi uses unsigned char for the data transmission. That is 8-bit. in other words values 0-255. So make sure the values in data do not exceed
272     *            this range, otherwise the numbers would overflow in the native code and unexpected results would yield
273     * @return return -1 on error
274     */
275    public static int wiringPiSPIDataRW(int channel, short[] data){
276        return wiringPiSPIDataRW(channel, data, data.length);
277    }
278}