mirror of
https://github.com/clockworkpi/WiringPi.git
synced 2025-12-12 16:08:49 +01:00
for kernels 4.8 onwards. Some very old stuff might break. Additional fixes for the ISR code and some tweaks here and there. I've removed the checks for some operations that might fail when using the gpiomem interface - which is now the default way of doing things - if your program segfaults, then you may need to use sudo on it.
165 lines
4.0 KiB
C
165 lines
4.0 KiB
C
/*
|
|
* 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 ;
|
|
}
|