mruby-linux-spi 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +28 -0
- data/README.md +44 -0
- data/lib/mruby/spi/version.rb +5 -0
- data/lib/mruby/spi.rb +240 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4a72961a5cd63b9763984c28407d942c81de8311e0780eb24e9bc371aedeaf56
|
4
|
+
data.tar.gz: 07034c750af72824ff3436e7ef44435c69ccb2b5b78cda3d25fde26238a14cab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 79d7b82d3217cbec07af1551c33c3af4404423913cdd986ee14367bf685c77432d62ce24cdb09012488bc28fe31b5a40624c0fa177beb99d8a2585b7532f30e8
|
7
|
+
data.tar.gz: 33b8175d33eb5a0d29db8b30689f1108bf7f8b4f2c567ed9c155b285564c267e7acf3fa9c99daed5c5a2b6f4a2d6a54e02f9f65abdbbbd7452993ed731ad0472
|
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2023, Shimane IT Open-Innovation Center.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
16
|
+
contributors may be used to endorse or promote products derived from
|
17
|
+
this software without specific prior written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# SPI class using Linux spidev.
|
2
|
+
|
3
|
+
 >> [source code](test/ADXL345_Accelerometer.rb)
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
This is an implementation of the SPI class library for Linux.
|
8
|
+
Follows [mruby, mruby/c common I/O API guidelines.](https://github.com/mruby/microcontroller-peripheral-interface-guide)
|
9
|
+
|
10
|
+
This library uses the Linux spidev device driver.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
$ gem install mruby-linux-spi
|
15
|
+
|
16
|
+
|
17
|
+
## Features
|
18
|
+
|
19
|
+
* This class defines only master devices and transfers in 8-bit units.
|
20
|
+
* The Chip Select (CS/SS) will be managed spidev device driver automatically.
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
about RaspberryPi...
|
25
|
+
|
26
|
+
```
|
27
|
+
# Connect pin #19 as MOSI, #21 as MISO, #23 as SCLK, #24 as CS.
|
28
|
+
|
29
|
+
require "mruby/spi"
|
30
|
+
|
31
|
+
# create instance
|
32
|
+
spi = SPI.new()
|
33
|
+
|
34
|
+
# read 4 bytes (send out 0x00 x 4bytes)
|
35
|
+
s = spi.read(4)
|
36
|
+
```
|
37
|
+
|
38
|
+
Other case, see original guidelines.
|
39
|
+
https://github.com/mruby/microcontroller-peripheral-interface-guide/blob/main/mruby_io_SPI_en.md
|
40
|
+
|
41
|
+
|
42
|
+
## Licence
|
43
|
+
|
44
|
+
BSD 3-Clause License. see LICENSE file.
|
data/lib/mruby/spi.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
#
|
2
|
+
# SPI class using Linux spidev.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2023 Shimane IT Open-Innovation Center.
|
5
|
+
#
|
6
|
+
# see: LICENSE file.
|
7
|
+
# see: https://github.com/mruby/microcontroller-peripheral-interface-guide/blob/main/mruby_io_SPI_en.md
|
8
|
+
#
|
9
|
+
# frozen_string_literal: true
|
10
|
+
#
|
11
|
+
|
12
|
+
require_relative "spi/version"
|
13
|
+
|
14
|
+
##
|
15
|
+
# SPI namespace
|
16
|
+
#
|
17
|
+
module SPI
|
18
|
+
|
19
|
+
MSB_FIRST = 0
|
20
|
+
LSB_FIRST = 1
|
21
|
+
|
22
|
+
|
23
|
+
##
|
24
|
+
# constructor
|
25
|
+
#
|
26
|
+
#@see SPI::LinuxSPIdev.initialize
|
27
|
+
#
|
28
|
+
def self.new(node = "/dev/spidev0.0", frequency:1_000_000, mode:0, first_bit:SPI::MSB_FIRST )
|
29
|
+
SPI::LinuxSPIdev.new(node, frequency, mode, first_bit)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
##
|
35
|
+
# Linux SPI Device driver
|
36
|
+
#
|
37
|
+
class SPI::LinuxSPIdev
|
38
|
+
|
39
|
+
# Constants
|
40
|
+
# see: /usr/include/linux/spi/spidev.h, /usr/include/asm-generic/ioctl.h
|
41
|
+
IOC_NONE = 0
|
42
|
+
IOC_WRITE = 1
|
43
|
+
IOC_READ = 2
|
44
|
+
SPI_IOC_MAGIC = 'k'.ord
|
45
|
+
|
46
|
+
# Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) (limited to 8 bits)
|
47
|
+
# define SPI_IOC_RD_MODE _IOR(SPI_IOC_MAGIC, 1, __u8)
|
48
|
+
# define SPI_IOC_WR_MODE _IOW(SPI_IOC_MAGIC, 1, __u8)
|
49
|
+
# _IOx( type, nr, size ) is bit mapped [RW][size:14][type:8][nr:8]
|
50
|
+
# dir | size | type | nr
|
51
|
+
SPI_IOC_RD_MODE = IOC_READ << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 1
|
52
|
+
SPI_IOC_WR_MODE = IOC_WRITE << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 1
|
53
|
+
|
54
|
+
# Read / Write SPI bit justification
|
55
|
+
# define SPI_IOC_RD_LSB_FIRST _IOR(SPI_IOC_MAGIC, 2, __u8)
|
56
|
+
# define SPI_IOC_WR_LSB_FIRST _IOW(SPI_IOC_MAGIC, 2, __u8)
|
57
|
+
# dir | size | type | nr
|
58
|
+
SPI_IOC_RD_LSB_FIRST = IOC_READ << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 2
|
59
|
+
SPI_IOC_WR_LSB_FIRST = IOC_WRITE << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 2
|
60
|
+
|
61
|
+
# Read / Write SPI device word length (1..N)
|
62
|
+
# define SPI_IOC_RD_BITS_PER_WORD _IOR(SPI_IOC_MAGIC, 3, __u8)
|
63
|
+
# define SPI_IOC_WR_BITS_PER_WORD _IOW(SPI_IOC_MAGIC, 3, __u8)
|
64
|
+
# dir | size | type | nr
|
65
|
+
SPI_IOC_RD_BITS_PER_WORD = IOC_READ << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 3
|
66
|
+
SPI_IOC_WR_BITS_PER_WORD = IOC_WRITE << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 3
|
67
|
+
|
68
|
+
# Read / Write SPI device default max speed hz
|
69
|
+
# define SPI_IOC_RD_MAX_SPEED_HZ _IOR(SPI_IOC_MAGIC, 4, __u32)
|
70
|
+
# define SPI_IOC_WR_MAX_SPEED_HZ _IOW(SPI_IOC_MAGIC, 4, __u32)
|
71
|
+
# dir | size | type | nr
|
72
|
+
SPI_IOC_RD_MAX_SPEED_HZ = IOC_READ << 30 | 4 << 16 | SPI_IOC_MAGIC << 8 | 4
|
73
|
+
SPI_IOC_WR_MAX_SPEED_HZ = IOC_WRITE << 30 | 4 << 16 | SPI_IOC_MAGIC << 8 | 4
|
74
|
+
|
75
|
+
# define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
|
76
|
+
# char[SPI_MSGSIZE(1) is 32 bytes.
|
77
|
+
# NOTE: struct layout is the same in 64bit and 32bit userspace.
|
78
|
+
# dir | size | type | nr
|
79
|
+
SPI_IOC_MESSAGE = IOC_WRITE << 30 |32 << 16 | SPI_IOC_MAGIC << 8 | 0
|
80
|
+
|
81
|
+
|
82
|
+
##
|
83
|
+
# constructor
|
84
|
+
#
|
85
|
+
#@param [String] node device node of SPI
|
86
|
+
#@param [Integer] frequency SCLK frequency.
|
87
|
+
#@param [Integer] mode SPI mode (0..3)
|
88
|
+
#@param [Constant] first_bit MSB_FIRST or LSB_FIRST
|
89
|
+
#@see SPI.new
|
90
|
+
#
|
91
|
+
def initialize(node, frequency, mode, first_bit)
|
92
|
+
@device = File.open(node, "r+:ASCII-8BIT")
|
93
|
+
|
94
|
+
_set_max_speed_hz( frequency )
|
95
|
+
_set_mode( mode )
|
96
|
+
_set_lsb_first( first_bit )
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
##
|
101
|
+
# Changes the operating mode (parameters) of the SPI.
|
102
|
+
#
|
103
|
+
#@param [Integer] frequency SCLK frequency.
|
104
|
+
#@param [Integer] mode SPI mode (0..3)
|
105
|
+
#@return [void]
|
106
|
+
#
|
107
|
+
def setmode( frequency:nil, mode:nil )
|
108
|
+
_set_max_speed_hz( frequency ) if frequency
|
109
|
+
_set_mode( mode ) if mode
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
##
|
114
|
+
# Reads data of read_bytes bytes from the SPI bus.
|
115
|
+
#
|
116
|
+
#@param [Integer] read_bytes read bytes.
|
117
|
+
#@return [String] reading datas.
|
118
|
+
#
|
119
|
+
def read( read_bytes )
|
120
|
+
@device.sysread( read_bytes )
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
##
|
125
|
+
# Outputs data specified in outputs to the SPI bus.
|
126
|
+
#
|
127
|
+
#@param [Integer,String,Array<Integer>] outputs output data.
|
128
|
+
#@return [nil]
|
129
|
+
#
|
130
|
+
def write( *outputs )
|
131
|
+
send_data = _rebuild_output_data( outputs )
|
132
|
+
@device.syswrite( send_data )
|
133
|
+
return nil
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
##
|
138
|
+
# Outputs data specified in outputs to the SPI bus while
|
139
|
+
# simultaneously reading data (General-purpose transfer).
|
140
|
+
#
|
141
|
+
#@param [Integer,String,Array<Integer>] outputs output data.
|
142
|
+
#@param [Integer] additional_read_bytes additional read bytes
|
143
|
+
#@return [String] reading datas.
|
144
|
+
#
|
145
|
+
def transfer( outputs, additional_read_bytes = 0 )
|
146
|
+
|
147
|
+
# prepare the send buffer and receive buffer.
|
148
|
+
send_data = _rebuild_output_data( [outputs] )
|
149
|
+
len = send_data.size
|
150
|
+
if additional_read_bytes > 0
|
151
|
+
send_data << ("\x00".b * additional_read_bytes)
|
152
|
+
len += additional_read_bytes
|
153
|
+
end
|
154
|
+
recv_data = "\x00".b * len
|
155
|
+
|
156
|
+
# prepare the struct spi_ioc_transfer. (spidev.h)
|
157
|
+
arg = [ [send_data].pack("P").unpack1("J"), # __u64 tx_buf;
|
158
|
+
[recv_data].pack("P").unpack1("J"), # __u64 rx_buf;
|
159
|
+
|
160
|
+
len, # __u32 len;
|
161
|
+
0, # __u32 speed_hz;
|
162
|
+
|
163
|
+
0, # __u16 delay_usecs;
|
164
|
+
0, # __u8 bits_per_word;
|
165
|
+
0, # __u8 cs_change;
|
166
|
+
0, # __u8 tx_nbits;
|
167
|
+
0, # __u8 rx_nbits;
|
168
|
+
0, # __u8 word_delay_usecs;
|
169
|
+
0, # __u8 pad;
|
170
|
+
].pack("QQLLSCCCCCC")
|
171
|
+
|
172
|
+
# trigger IOCTL.
|
173
|
+
@device.ioctl( SPI_IOC_MESSAGE, arg )
|
174
|
+
return recv_data
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
private
|
179
|
+
def _get_mode()
|
180
|
+
arg = "\x00".b
|
181
|
+
@device.ioctl( SPI_IOC_RD_MODE, arg )
|
182
|
+
return arg.unpack("C")[0]
|
183
|
+
end
|
184
|
+
|
185
|
+
def _set_mode( mode )
|
186
|
+
arg = [mode].pack("C")
|
187
|
+
@device.ioctl( SPI_IOC_WR_MODE, arg )
|
188
|
+
end
|
189
|
+
|
190
|
+
def _get_lsb_first()
|
191
|
+
arg = "\x00".b
|
192
|
+
@device.ioctl( SPI_IOC_RD_LSB_FIRST, arg )
|
193
|
+
return arg.unpack("C")[0]
|
194
|
+
end
|
195
|
+
|
196
|
+
def _set_lsb_first( flag )
|
197
|
+
#(note) Legal operation could not be confirmed with RasPi OS ioctl.
|
198
|
+
arg = [flag].pack("C")
|
199
|
+
@device.ioctl( SPI_IOC_WR_LSB_FIRST, arg )
|
200
|
+
end
|
201
|
+
|
202
|
+
def _get_bits_per_word()
|
203
|
+
arg = "\x00".b
|
204
|
+
@device.ioctl( SPI_IOC_RD_BITS_PER_WORD, arg )
|
205
|
+
return arg.unpack("C")[0]
|
206
|
+
end
|
207
|
+
|
208
|
+
def _set_bits_per_word( bits_per_word )
|
209
|
+
arg = [bits_per_word].pack("C")
|
210
|
+
@device.ioctl( SPI_IOC_WR_BITS_PER_WORD, arg )
|
211
|
+
end
|
212
|
+
|
213
|
+
def _get_max_speed_hz()
|
214
|
+
arg = "\x00\x00\x00\x00".b
|
215
|
+
@device.ioctl( SPI_IOC_RD_MAX_SPEED_HZ, arg )
|
216
|
+
return arg.unpack("L")[0]
|
217
|
+
end
|
218
|
+
|
219
|
+
def _set_max_speed_hz( freq )
|
220
|
+
arg = [freq].pack("L")
|
221
|
+
@device.ioctl( SPI_IOC_WR_MAX_SPEED_HZ, arg )
|
222
|
+
end
|
223
|
+
|
224
|
+
def _rebuild_output_data( arg )
|
225
|
+
data = "".b
|
226
|
+
arg.flatten.each {|d|
|
227
|
+
case d
|
228
|
+
when Integer
|
229
|
+
data << d.chr
|
230
|
+
when String
|
231
|
+
data << d.force_encoding(Encoding::ASCII_8BIT)
|
232
|
+
else
|
233
|
+
raise ArgumentError
|
234
|
+
end
|
235
|
+
}
|
236
|
+
|
237
|
+
return data
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mruby-linux-spi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- HirohitoHigashi
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-10-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- higashi@s-itoc.jp
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
- lib/mruby/spi.rb
|
23
|
+
- lib/mruby/spi/version.rb
|
24
|
+
homepage: https://github.com/HirohitoHigashi/mruby-mio/tree/main/mruby-linux-spi
|
25
|
+
licenses: []
|
26
|
+
metadata:
|
27
|
+
homepage_uri: https://github.com/HirohitoHigashi/mruby-mio/tree/main/mruby-linux-spi
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.6.0
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubygems_version: 3.4.13
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: SPI bus driver class library using Linux spidev.
|
47
|
+
test_files: []
|