diff --git a/R/RcppExports.R b/R/RcppExports.R index 5b84066..1382650 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -1,16 +1,7 @@ # Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 -#' Title -#' -#' @param mystuff -#' @param morestuff -#' -#' @return -#' @export -#' -#' @examples -rpi_spi_WriteAndRead <- function(mystuff, morestuff) { - .Call(`_rpigpior_rpi_spi_WriteAndRead`, mystuff, morestuff) +rpi_spi_open <- function(*device, config) { + .Call(`_rpigpior_rpi_spi_open`, *device, config) } diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index ea8e1bf..33a267b 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -10,21 +10,21 @@ Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); #endif -// rpi_spi_WriteAndRead -int rpi_spi_WriteAndRead(int mystuff, char morestuff); -RcppExport SEXP _rpigpior_rpi_spi_WriteAndRead(SEXP mystuffSEXP, SEXP morestuffSEXP) { +// rpi_spi_open +int rpi_spi_open(char *device, spi_config_t config); +RcppExport SEXP _rpigpior_rpi_spi_open(SEXP *deviceSEXP, SEXP configSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< int >::type mystuff(mystuffSEXP); - Rcpp::traits::input_parameter< char >::type morestuff(morestuffSEXP); - rcpp_result_gen = Rcpp::wrap(rpi_spi_WriteAndRead(mystuff, morestuff)); + Rcpp::traits::input_parameter< char >::type *device(*deviceSEXP); + Rcpp::traits::input_parameter< spi_config_t >::type config(configSEXP); + rcpp_result_gen = Rcpp::wrap(rpi_spi_open(*device, config)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { - {"_rpigpior_rpi_spi_WriteAndRead", (DL_FUNC) &_rpigpior_rpi_spi_WriteAndRead, 2}, + {"_rpigpior_rpi_spi_open", (DL_FUNC) &_rpigpior_rpi_spi_open, 2}, {NULL, NULL, 0} }; diff --git a/src/rpi_spi_WriteAndRead.cpp b/src/rpi_spi_WriteAndRead.cpp deleted file mode 100644 index 15fb936..0000000 --- a/src/rpi_spi_WriteAndRead.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include -using namespace Rcpp; - -// [[Rcpp::export]] - -int rpi_spi_WriteAndRead(int mystuff, char morestuff) {} diff --git a/src/spi.c b/src/spi.c deleted file mode 100644 index 26b0cbe..0000000 --- a/src/spi.c +++ /dev/null @@ -1,180 +0,0 @@ -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} -{ } -{ Filename: spi.c } -{ Copyright(c): Leon de Boer(LdB) 2019, 2020 } -{ Version: 1.10 } -{ } -{***************************************************************************} -{ } -{ Defines an API interface for the SPI devices on Linux } -{ } -{++++++++++++++++++++++++[ REVISIONS ]++++++++++++++++++++++++++++++++++++++} -{ 1.00 Initial version } -{ 1.10 Compacted stuct fields } -{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -#include // C standard unit for bool, true, false -#include // C standard unit for uint32_t etc -#include // Needed for SPI port -#include // Needed for SPI port -#include // Needed for SPI port -#include // Needed for SPI port -#include // neded for sprintf_s -#include // Posix thread unit -#include // Linux Semaphore unit -#include "spi.h" // This units header - -#if SPI_DRIVER_VERSION != 1100 -#error "Header does not match this version of file" -#endif - -struct spi_device -{ - int spi_fd; // File descriptor for the SPI device - uint32_t spi_speed; // SPI speed - sem_t lock; // Semaphore for lock - struct { - uint16_t spi_bitsPerWord: 8; // SPI bits per word - uint16_t spi_num : 4; // SPI device table number - uint16_t _reserved: 2; // reserved - uint16_t uselocks : 1; // Locks to be used for access - uint16_t inuse : 1; // In use flag - }; -}; - -/* Global table of SPI devices. */ -static struct spi_device spitab[NSPI] = { {0} }; - -/*-[ SpiOpenPort ]----------------------------------------------------------} -. Creates a SPI handle which provides access to the SPI device number. -. The SPI device is setup to the bits, speed and mode provided. -. RETURN: valid SPI_HANDLE for success, NULL for any failure -.--------------------------------------------------------------------------*/ -SPI_HANDLE SpiOpenPort (uint8_t spi_devicenum, uint8_t bit_exchange_size, uint32_t speed, uint8_t mode, bool useLock) -{ - SPI_HANDLE spi = 0; // Preset null handle - struct spi_device* spi_ptr = &spitab[spi_devicenum]; // SPI device pointer - if (spi_devicenum < NSPI && spi_ptr->inuse == 0 && speed != 0) - { - spi_ptr->spi_fd = 0; // Zero SPI file device - spi_ptr->spi_num = spi_devicenum; // Hold spi device number - spi_ptr->spi_bitsPerWord = bit_exchange_size; // Hold SPI exchange size - spi_ptr->spi_speed = speed; // Hold SPI speed setting - spi_ptr->uselocks = (useLock == true) ? 1 : 0; // Set use lock - if (useLock) // Using locks - { - sem_init(&spi_ptr->lock, 0, 1); // Initialize mutex to 1 - } - uint8_t spi_mode = mode; - uint8_t spi_bitsPerWord = bit_exchange_size; - char buf[256] = { 0 }; - sprintf(&buf[0], "/dev/spidev0.%c", (char)(0x30 + spi_devicenum)); - int fd = open(&buf[0], O_RDWR); // Open the SPI device - if (fd >= 0) // SPI device opened correctly - { - spi_ptr->spi_fd = fd; // Hold the file device to SPI - if (ioctl(spi_ptr->spi_fd, SPI_IOC_WR_MODE, &spi_mode) >= 0 && - ioctl(spi_ptr->spi_fd, SPI_IOC_RD_MODE, &spi_mode) >= 0 && - ioctl(spi_ptr->spi_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bitsPerWord) >= 0 && - ioctl(spi_ptr->spi_fd, SPI_IOC_RD_BITS_PER_WORD, &spi_bitsPerWord) >= 0 && - ioctl(spi_ptr->spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_ptr->spi_speed) >= 0 && - ioctl(spi_ptr->spi_fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi_ptr->spi_speed) >= 0) - { - spi_ptr->inuse = 1; // The handle is now in use - spi = spi_ptr; // Return SPI handle - } - } - } - return(spi); // Return SPI handle result -} - -/*-[ SpiClosePort ]---------------------------------------------------------} -. Given a valid SPI handle the access is released and the handle freed. -. RETURN: true for success, false for any failure -.--------------------------------------------------------------------------*/ -bool SpiClosePort (SPI_HANDLE spiHandle) -{ - if (spiHandle && spiHandle->inuse) // SPI handle valid and SPI handle is in use - { - if (spiHandle->uselocks) // Using locks - { - sem_destroy(&spiHandle->lock); // Destroy lock mutex - } - close(spiHandle->spi_fd); // Close the spi handle - spiHandle->spi_fd = 0; // Zero the SPI handle - spiHandle->spi_num = 0; // Zero SPI handle number - spiHandle->inuse = 0; // The SPI handle is now free - return true; // Return success - } - return false; // Return failure -} - -/*-[ rpi_spi_WriteAndRead ]------------------------------------------------------} -. Given a valid SPI handle and valid data pointers the call will send and -. receive data to and from the buffer pointers. As the write occurs before -. the read the buffer pointers can be the same buffer space. -. RETURN: >= 0 transfer count for success, < 0 for any error -.--------------------------------------------------------------------------*/ -int rpi_spi_WriteAndRead (SPI_HANDLE spiHandle, uint8_t* TxData, uint8_t* RxData, uint16_t Length, bool LeaveCsLow) -{ - int retVal = -1; // Preset -1 - if (spiHandle && spiHandle->inuse) // SPI handle valid and SPI handle is in use - { - if (spiHandle->uselocks) // Using locks - { - sem_wait(&spiHandle->lock); // Take semaphore - } - struct spi_ioc_transfer spi = { 0 }; - spi.tx_buf = (unsigned long)TxData; // transmit from "data" - spi.rx_buf = (unsigned long)RxData; // receive into "data" - spi.len = Length; // length of data to tx/rx - spi.delay_usecs = 0; // Delay before sending - spi.speed_hz = spiHandle->spi_speed; // Speed for transfer - spi.bits_per_word = spiHandle->spi_bitsPerWord; // Bits per exchange - spi.cs_change = LeaveCsLow; // 0=Set CS high after a transfer, 1=leave CS set low - retVal = ioctl(spiHandle->spi_fd, SPI_IOC_MESSAGE(1), &spi);// Execute exchange - if (spiHandle->uselocks) // Using locks - { - sem_post(&spiHandle->lock); // Give semaphore - } - } - return retVal; // Return result -} - -/*-[ rpi_spi_WriteBlockRepeat ]--------------------------------------------------} -. Given a valid SPI handle and valid data pointers the call will send the -. data block repeat times. It is used to speed up things like writing to SPI -. LCD screen with areas a fixed colour. -. RETURN: >= 0 blocks transfered for success, < 0 for any error -.--------------------------------------------------------------------------*/ -int rpi_spi_WriteBlockRepeat (SPI_HANDLE spiHandle, uint8_t* TxBlock, uint16_t TxBlockLen, uint32_t Repeats, bool LeaveCsLow) -{ - int retVal = -1; // Preset -1 - if (spiHandle && TxBlock && spiHandle->inuse) // SPI handle and TxBlock valid and SPI handle is in use - { - if (spiHandle->uselocks) // Using locks - { - sem_wait(&spiHandle->lock); // Take semaphore - } - struct spi_ioc_transfer spi = { 0 }; - spi.tx_buf = (unsigned long)TxBlock; // transmit from "data" - spi.rx_buf = (unsigned long)0; // receive into "data" - spi.len = TxBlockLen; // length of data to tx/rx - spi.delay_usecs = 0; // Delay before sending - spi.speed_hz = spiHandle->spi_speed; // Speed for transfer - spi.bits_per_word = spiHandle->spi_bitsPerWord; // Bits per exchange - spi.cs_change = LeaveCsLow; // 0=Set CS high after a transfer, 1=leave CS set low - retVal = 0; // Zero retVal - uint32_t j; - for (j = 0; j < Repeats && retVal == TxBlockLen; j++) // For each block repeat - { - retVal = ioctl(spiHandle->spi_fd, SPI_IOC_MESSAGE(1), &spi);// Execute exchange - } - retVal = j; // Return block count - if (spiHandle->uselocks) // Using locks - { - sem_post(&spiHandle->lock); // Give semaphore - } - } - return retVal; // Return result -} diff --git a/src/spi.h b/src/spi.h deleted file mode 100644 index 9c22168..0000000 --- a/src/spi.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _SPI_H_ -#define _SPI_H_ - -#ifdef __cplusplus // If we are including to a C++ -extern "C" { // Put extern C directive wrapper around -#endif - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++} -{ } -{ Filename: spi.h } -{ Copyright(c): Leon de Boer(LdB) 2019, 2020 } -{ Version: 1.10 } -{ } -{***************************************************************************} -{ } -{ Defines an API interface for the SPI devices on Linux } -{ } -{++++++++++++++++++++++++[ REVISIONS ]++++++++++++++++++++++++++++++++++++++} -{ 1.00 Initial version } -{ 1.10 Compacted stuct fields } -{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -#include // C standard unit for bool, true, false -#include // C standard unit for uint32_t etc - -#define SPI_DRIVER_VERSION 1100 // Version number 1.10 build 0 - -typedef struct spi_device* SPI_HANDLE; // Define an SPI_HANDLE pointer to opaque internal struct - -#define NSPI 2 // 2 SPI devices supported - - -/*-[ SpiOpenPort ]----------------------------------------------------------} -. Creates a SPI handle which provides access to the SPI device number. -. The SPI device is setup to the bits, speed and mode provided. -. RETURN: valid SPI_HANDLE for success, NULL for any failure -.--------------------------------------------------------------------------*/ -SPI_HANDLE SpiOpenPort (uint8_t spi_devicenum, uint8_t bit_exchange_size, uint32_t speed, uint8_t mode, bool useLock); - -/*-[ SpiClosePort ]---------------------------------------------------------} -. Given a valid SPI handle the access is released and the handle freed. -. RETURN: true for success, false for any failure -.--------------------------------------------------------------------------*/ -bool SpiClosePort (SPI_HANDLE spiHandle); - -/*-[ SpiWriteAndRead ]------------------------------------------------------} -. Given a valid SPI handle and valid data pointers the call will send and -. receive data to and from the buffer pointers. As the write occurs before -. the read the buffer pointers can be the same buffer space. -. RETURN: >= 0 transfer count for success, < 0 for any error -.--------------------------------------------------------------------------*/ -int SpiWriteAndRead (SPI_HANDLE spiHandle, uint8_t* TxData, uint8_t* RxData, uint16_t Length, bool LeaveCsLow); - -/*-[ SpiWriteBlockRepeat ]--------------------------------------------------} -. Given a valid SPI handle and valid data pointers the call will send the -. data block count times. It is used to speed up things like writing LCD -. SPI screen areas a fixed colour. -. RETURN: >= 0 blocks transfered for success, < 0 for any error -.--------------------------------------------------------------------------*/ -int SpiWriteBlockRepeat (SPI_HANDLE spiHandle, uint8_t* TxBlock, uint16_t TxBlockLen, uint32_t Repeats, bool LeaveCsLow); - -#ifdef __cplusplus // If we are including to a C++ file -} // Close the extern C directive wrapper -#endif - -#endif \ No newline at end of file