/* * 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 . *********************************************************************** */ #include #include #include #include #include #include #include #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 ; }