/* * wiringPiSPI.c: * Simplified SPI access routines * Copyright (c) 2012 Gordon Henderson *********************************************************************** * 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 "wiringPiSPI.h" // The SPI bus parameters // Variables as they need to be passed as pointers later on static char *spiDev0 = "/dev/spidev0.0" ; static char *spiDev1 = "/dev/spidev0.1" ; static uint8_t spiMode = 0 ; static uint8_t spiBPW = 8 ; static uint16_t spiDelay = 0; static uint32_t spiSpeeds [2] ; static int spiFds [2] ; /* * wiringPiSPIGetFd: * Return the file-descriptor for the given channel ********************************************************************************* */ int wiringPiSPIGetFd (int channel) { return spiFds [channel & 1] ; } /* * wiringPiSPIDataRW: * Write and Read a block of data over the SPI bus. * Note the data ia being read into the transmit buffer, so will * overwrite it! * This is also a full-duplex operation. ********************************************************************************* */ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) { struct spi_ioc_transfer spi ; channel &= 1 ; spi.tx_buf = (unsigned long)data ; spi.rx_buf = (unsigned long)data ; spi.len = len ; spi.delay_usecs = spiDelay ; spi.speed_hz = spiSpeeds [channel] ; spi.bits_per_word = spiBPW ; return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ; } /* * wiringPiSPISetup: * Open the SPI device, and set it up, etc. ********************************************************************************* */ int wiringPiSPISetup (int channel, int speed) { int fd ; channel &= 1 ; if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) return -1 ; spiSpeeds [channel] = speed ; spiFds [channel] = fd ; // Set SPI parameters. // Why are we reading it afterwriting it? I've no idea, but for now I'm blindly // copying example code I've seen online... if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0) return -1 ; if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0) return -1 ; if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ; if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ; if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) return -1 ; if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) return -1 ; return fd ; }