| /* |
| * gertboard.c: |
| * Access routines for the SPI devices on the Gertboard |
| * Copyright (c) 2012 Gordon Henderson |
| * |
| * The Gertboard has: |
| * |
| * An MCP3002 dual-channel A to D convertor connected |
| * to the SPI bus, selected by chip-select A, and: |
| * |
| * An MCP4802 dual-channel D to A convertor connected |
| * to the SPI bus, selected via chip-select B. |
| * |
| *********************************************************************** |
| * This file is part of wiringPi: |
| * https://projects.drogon.net/raspberry-pi/wiringpi/ |
| * |
| * wiringPi is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU Lesser General Public License as |
| * published by the Free Software Foundation, either version 3 of the |
| * License, or (at your option) any later version. |
| * |
| * wiringPi is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with wiringPi. |
| * If not, see <http://www.gnu.org/licenses/>. |
| *********************************************************************** |
| */ |
| |
| |
| #include <stdio.h> |
| #include <stdint.h> |
| #include <fcntl.h> |
| #include <sys/ioctl.h> |
| #include <linux/spi/spidev.h> |
| |
| #include <wiringPi.h> |
| #include <wiringPiSPI.h> |
| |
| #include "gertboard.h" |
| |
| // The A-D convertor won't run at more than 1MHz @ 3.3v |
| |
| #define SPI_ADC_SPEED 1000000 |
| #define SPI_DAC_SPEED 1000000 |
| #define SPI_A2D 0 |
| #define SPI_D2A 1 |
| |
| |
| /* |
| * gertboardAnalogWrite: |
| * Write an 8-bit data value to the MCP4802 Analog to digital |
| * convertor on the Gertboard. |
| ********************************************************************************* |
| */ |
| |
| void gertboardAnalogWrite (const int chan, const int value) |
| { |
| uint8_t spiData [2] ; |
| uint8_t chanBits, dataBits ; |
| |
| if (chan == 0) |
| chanBits = 0x30 ; |
| else |
| chanBits = 0xB0 ; |
| |
| chanBits |= ((value >> 4) & 0x0F) ; |
| dataBits = ((value << 4) & 0xF0) ; |
| |
| spiData [0] = chanBits ; |
| spiData [1] = dataBits ; |
| |
| wiringPiSPIDataRW (SPI_D2A, spiData, 2) ; |
| } |
| |
| |
| /* |
| * gertboardAnalogRead: |
| * Return the analog value of the given channel (0/1). |
| * The A/D is a 10-bit device |
| ********************************************************************************* |
| */ |
| |
| int gertboardAnalogRead (const int chan) |
| { |
| uint8_t spiData [2] ; |
| |
| uint8_t chanBits ; |
| |
| if (chan == 0) |
| chanBits = 0b11010000 ; |
| else |
| chanBits = 0b11110000 ; |
| |
| spiData [0] = chanBits ; |
| spiData [1] = 0 ; |
| |
| wiringPiSPIDataRW (SPI_A2D, spiData, 2) ; |
| |
| return ((spiData [0] << 8) | (spiData [1] >> 1)) & 0x3FF ; |
| } |
| |
| |
| /* |
| * gertboardSPISetup: |
| * Initialise the SPI bus, etc. |
| ********************************************************************************* |
| */ |
| |
| int gertboardSPISetup (void) |
| { |
| if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0) |
| return -1 ; |
| |
| if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0) |
| return -1 ; |
| |
| return 0 ; |
| } |
| |
| |
| /* |
| * New wiringPi node extension methods. |
| ********************************************************************************* |
| */ |
| |
| static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan) |
| { |
| return gertboardAnalogRead (chan - node->pinBase) ; |
| } |
| |
| static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value) |
| { |
| gertboardAnalogWrite (chan - node->pinBase, value) ; |
| } |
| |
| |
| /* |
| * gertboardAnalogSetup: |
| * Create a new wiringPi device node for the analog devices on the |
| * Gertboard. We create one node with 2 pins - each pin being read |
| * and write - although the operations actually go to different |
| * hardware devices. |
| ********************************************************************************* |
| */ |
| |
| int gertboardAnalogSetup (const int pinBase) |
| { |
| struct wiringPiNodeStruct *node ; |
| int x ; |
| |
| if (( x = gertboardSPISetup ()) != 0) |
| return x; |
| |
| node = wiringPiNewNode (pinBase, 2) ; |
| node->analogRead = myAnalogRead ; |
| node->analogWrite = myAnalogWrite ; |
| |
| return 0 ; |
| } |