Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linuxfs used for SPI operations. .. Most this code base is from mpil… #434

Merged
merged 4 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion pi4j-core/src/main/java/com/pi4j/io/spi/Spi.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ public interface Spi extends IO<Spi, SpiConfig, SpiProvider>, AutoCloseable, IOD
SpiChipSelect DEFAULT_CHIP_SELECT = SpiChipSelect.CS_0;
/** Constant <code>DEFAULT_BAUD=1000000</code> */
int DEFAULT_BAUD = 1000000; // 1MHz (range is 500kHz - 32MHz)

/** Constant <code>DEFAULT_WRITE_LSB_FIRST</code> */
int DEFAULT_WRITE_LSB_FIRST = 0;
/** Constant <code>DEFAULT_READ_LSB_FIRST</code> */
int DEFAULT_READ_LSB_FIRST = 0;
/**
* <p>newConfigBuilder.</p>
*
Expand Down
72 changes: 72 additions & 0 deletions pi4j-core/src/main/java/com/pi4j/io/spi/SpiConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public interface SpiConfig extends AddressConfig<SpiConfig>, IOConfig<SpiConfig>
String MODE_KEY = "mode";
/** Constant <code>FLAGS_KEY="flags"</code> */
String FLAGS_KEY = "flags";
/** Constant <code>WRITE_LSB_KEY="baud"</code> */
String WRITE_LSB_KEY = "write_lsb";
/** Constant <code>READ_LSB_KEY="baud"</code> */
String READ_LSB_KEY = "read_lsb";



/**
* <p>newBuilder.</p>
Expand All @@ -68,6 +74,42 @@ static SpiConfigBuilder newBuilder(Context context) {
*/
default Integer getBaud() { return baud(); }

/**
* <p>ReadLsbFirst.</p>
* In accordance with the flags parm, Read operations
* 0 is LSB bit shifted first, 1 MSB bit shifted first
*
* @return a {@link java.lang.Integer} object.
*/
Integer readLsbFirst();

/**
* <p>getreadLsbfISRT.</p>
*
* @return a {@link java.lang.Integer} object.
*/
default Integer getReadLsbFirst() { return readLsbFirst(); }



/**
* <p>WriteLsbFirst.</p>
* In accordance with the flags parm, Write operations
* 0 is LSB bit shifted first, 1 MSB bit shifted first
*
* @return a {@link java.lang.Integer} object.
*/
Integer writeLsbFirst();

/**
* <p>getreadLsbfISRT.</p>
*
* @return a {@link java.lang.Integer} object.
*/
default Integer getWriteLsbFirst() { return writeLsbFirst(); }



/**
* <p>bus.</p>
* <p>If the Bus value is configured, that SpiBus
Expand Down Expand Up @@ -100,6 +142,36 @@ default boolean getBusUserProvided(){
return busUserProvided();
}

/**
* <p>writeLsbFirstserProvided.</p>
* @return a boolean.
*/
boolean writeLsbFirstUserProvided();

/**
* <p>getWriteLsbFirstUserProvided.</p>
* @return a {@link java.lang.Boolean} object.
*/
default boolean getWriteLsbFIrstUserProvided(){
return writeLsbFirstUserProvided();
}

/**
* <p>writeLsbFirstserProvided.</p>
* @return a boolean.
*/
boolean readLsbFirstUserProvided();

/**
* <p>getReadLsbFirstUserProvided.</p>
* @return a {@link java.lang.Boolean} object.
*/
default boolean getReadLsbFIrstUserProvided(){
return readLsbFirstUserProvided();
}




/**
* <p>mode.</p>
Expand Down
19 changes: 19 additions & 0 deletions pi4j-core/src/main/java/com/pi4j/io/spi/SpiConfigBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ static SpiConfigBuilder newInstance(Context context) {
return DefaultSpiConfigBuilder.newInstance(context);
}

/**
* <p>readLsbFirst.</p>
*
* @param shift a {@link java.lang.Integer} object.
* @return a {@link com.pi4j.io.spi.SpiConfigBuilder} object.
*/
SpiConfigBuilder readLsbFirst(Integer shift);

/**
* <p>writeLsbFirst.</p>
*
* @param shift a {@link java.lang.Integer} object.
* @return a {@link com.pi4j.io.spi.SpiConfigBuilder} object.
*/
SpiConfigBuilder writeLsbFirst(Integer shift);



/**
* <p>baud.</p>
*
Expand All @@ -55,6 +73,7 @@ static SpiConfigBuilder newInstance(Context context) {
*/
SpiConfigBuilder baud(Integer rate);


/**
* <p>bus.</p>
* <p>If the Bus value is configured, that SpiBus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public class DefaultSpiConfig
protected final SpiBus bus;
protected boolean busUserProvided = false; // indicate user supplied the value
protected final Long flags;
protected final int readLsbFirst;
protected final int writeLsbFirst;
protected boolean readLsbFirstUserProvided;
protected boolean writeLsbFirstUserProvided;

/**
* PRIVATE CONSTRUCTOR
Expand All @@ -73,6 +77,20 @@ protected DefaultSpiConfig(Map<String,String> properties){
this.busUserProvided = false;
}

if(properties.containsKey(WRITE_LSB_KEY)){
this.writeLsbFirst = StringUtil.parseInteger(properties.get(WRITE_LSB_KEY),Spi.DEFAULT_WRITE_LSB_FIRST);
this.writeLsbFirstUserProvided = true;
}else {
this.writeLsbFirst = 0;
this.writeLsbFirstUserProvided = false;
}
if(properties.containsKey(READ_LSB_KEY)){
this.readLsbFirst = StringUtil.parseInteger(properties.get(READ_LSB_KEY),Spi.DEFAULT_READ_LSB_FIRST);
this.readLsbFirstUserProvided = true;
}else {
this.readLsbFirst = 0;
this.readLsbFirstUserProvided = false;
}
// load optional MODE from properties
if(properties.containsKey(MODE_KEY)){
this.mode = SpiMode.parse(properties.get(MODE_KEY));
Expand All @@ -86,7 +104,7 @@ protected DefaultSpiConfig(Map<String,String> properties){
if(properties.containsKey(FLAGS_KEY)){
this.flags = StringUtil.parseLong(properties.get(FLAGS_KEY), null);
} else {
this.flags = 0L; // default flags (0)
this.flags = null; // set null, same as parseLong would
}

// define default property values if any are missing (based on the required address value)
Expand All @@ -101,13 +119,34 @@ public Integer baud() {
return this.baud;
}

@Override
public Integer readLsbFirst() {
return this.readLsbFirst;
}

@Override
public Integer writeLsbFirst() {
return this.writeLsbFirst;
}

/** {@inheritDoc} */
@Override
public boolean busUserProvided() {
return this.busUserProvided;
}


/** {@inheritDoc} */
@Override
public boolean writeLsbFirstUserProvided() {
return this.writeLsbFirstUserProvided;
}
/** {@inheritDoc} */
@Override
public boolean readLsbFirstUserProvided() {
return this.readLsbFirstUserProvided;
}


/** {@inheritDoc} */
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ public static SpiConfigBuilder newInstance(Context context) {
return new DefaultSpiConfigBuilder(context);
}

@Override
public SpiConfigBuilder readLsbFirst(Integer shift) {
this.properties.put(SpiConfig.READ_LSB_KEY, shift.toString());
return this;
}

@Override
public SpiConfigBuilder writeLsbFirst(Integer shift) {
this.properties.put(SpiConfig.WRITE_LSB_KEY, shift.toString());
return this;
}

/** {@inheritDoc} */
@Override
public SpiConfigBuilder baud(Integer rate) {
Expand Down
5 changes: 5 additions & 0 deletions plugins/pi4j-plugin-linuxfs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
<artifactId>jsch</artifactId>
<version>${jsch.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna.version}</version>
</dependency>
<dependency>
<groupId>com.pi4j</groupId>
<artifactId>pi4j-library-linuxfs</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.pi4j.plugin.linuxfs.provider.gpio.digital.LinuxFsDigitalOutputProvider;
import com.pi4j.plugin.linuxfs.provider.pwm.LinuxFsPwmProvider;
import com.pi4j.plugin.linuxfs.internal.LinuxPwm;
import com.pi4j.plugin.linuxfs.provider.spi.LinuxFsSpiProvider;
import com.pi4j.provider.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -100,14 +101,15 @@ public class LinuxFsPlugin implements Plugin {
public static final String I2C_PROVIDER_NAME = NAME + " I2C Provider";
public static final String I2C_PROVIDER_ID = ID + "-i2c";

// // SPI Provider name and unique ID
// public static final String SPI_PROVIDER_NAME = NAME + " SPI Provider";
// public static final String SPI_PROVIDER_ID = ID + "-spi";
//

// // Serial Provider name and unique ID
// public static final String SERIAL_PROVIDER_NAME = NAME + " Serial Provider";
// public static final String SERIAL_PROVIDER_ID = ID + "-serial";

// SPI Provider name and unique ID
public static final String SPI_PROVIDER_NAME = NAME + " SPI Provider";
public static final String SPI_PROVIDER_ID = ID + "-spi";

public static String DEFAULT_GPIO_FILESYSTEM_PATH = LinuxGpio.DEFAULT_SYSTEM_PATH;
public static String DEFAULT_PWM_FILESYSTEM_PATH = LinuxPwm.DEFAULT_SYSTEM_PATH;

Expand Down Expand Up @@ -155,7 +157,8 @@ public void initialize(PluginService service) {
LinuxFsDigitalInputProvider.newInstance(gpioFileSystemPath),
LinuxFsDigitalOutputProvider.newInstance(gpioFileSystemPath),
LinuxFsPwmProvider.newInstance(pwmFileSystemPath, pwmChip),
LinuxFsI2CProvider.newInstance()
LinuxFsI2CProvider.newInstance(),
LinuxFsSpiProvider.newInstance()
};

// register the LinuxFS I/O Providers with the plugin service
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* * Copyright (C) 2012 - 2024 Pi4J
* * %%
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* -
* #%L
* **********************************************************************
* ORGANIZATION : Pi4J
* PROJECT : Pi4J :: EXTENSION
* FILENAME : LinuxLibC.java
*
* This file is part of the Pi4J project. More information about
* this project can be found here: https://pi4j.com/
* **********************************************************************
* %%
*/

package com.pi4j.plugin.linuxfs.internal;

import com.sun.jna.Library;
import com.sun.jna.Native;

/**
* C library functions.
*
* @author mpilone
* @since 10/3/24.
*/
public interface LinuxLibC extends Library {

LinuxLibC INSTANCE = LinuxLibC.LibLoader.load();

class LibLoader {
static LinuxLibC load() {
return Native.load("c", LinuxLibC.class);
}
}

///////////////////////////////////
// fcntl.h
int O_WRONLY = 00000001;
int O_RDWR = 00000002;
int O_NONBLOCK = 00004000;

///////////////////////////////////
// ioctl.h
int _IOC_NRBITS = 8;
int _IOC_TYPEBITS = 8;
int _IOC_SIZEBITS = 14;

int _IOC_NRSHIFT = 0;
int _IOC_TYPESHIFT = (_IOC_NRSHIFT + _IOC_NRBITS);
int _IOC_SIZESHIFT = (_IOC_TYPESHIFT + _IOC_TYPEBITS);
int _IOC_DIRSHIFT = (_IOC_SIZESHIFT + _IOC_SIZEBITS);

byte _IOC_NONE = 0;
byte _IOC_WRITE = 1;
byte _IOC_READ = 2;

static int _IOC(byte dir, byte type, byte nr, int size) {
return (((dir) << _IOC_DIRSHIFT) |
((type) << _IOC_TYPESHIFT) |
((nr) << _IOC_NRSHIFT) |
((size) << _IOC_SIZESHIFT));
}

int ioctl(int filedes, long op, Object... args);

int open(String pathname, int flags);

int close(int fd);
}
Loading
Loading