chip-gpio 0.0.6 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d947a58cc0720824366acfc1489e499e0df866f3
4
- data.tar.gz: aa47ac588ab2ac5f9621e9919df0c4bca17033c4
3
+ metadata.gz: a0aadd6093c95dca4fe6b0954d49b95f83939f31
4
+ data.tar.gz: a0d02a82de5cf742972635168fbebd2b5e5313bd
5
5
  SHA512:
6
- metadata.gz: 7298e2dcedd3e0bd35ac87eed2fe62f0dec97439682232b5bc4d5b11c98bf57f387e0bc3e17751c30285e26ea9c2ecdff353b8cdd72b1d67520e90a3b4adfa31
7
- data.tar.gz: 512e252e8dc169bffa8522d1aaf17f4986e32a364534c7324367399e67f9f9319e5831d8f95c0edfec0caa38232c2c9a544328c011954eb5fa876390fb75c948
6
+ metadata.gz: d4c585a8fba5f94e479cc001ffabdc8cbd5409f3bfca5051c517063f400e8b39f0ba6609ee769b0b14488d28352d08c5d169be5d188a5c6b78c67cca270b8d66
7
+ data.tar.gz: '038d8703191146132f6882a9d38cf5906baa3be0b7cd337b77146d3199ddb5a1cc41451b3fb17734561000c357c66a6f70344e246633e670f49558b2f1ecea71'
@@ -0,0 +1,170 @@
1
+ module ChipGPIO
2
+ class HardwareSPI
3
+ attr_reader :polarity
4
+ attr_reader :phase
5
+ attr_reader :word_size
6
+ attr_reader :lsb_first
7
+ attr_reader :mode
8
+ attr_reader :speed_hz
9
+
10
+ SPI_MAX_CHUNK_BYTES = 64
11
+
12
+ SPI_IOC_RD_MODE = 0x80016b01
13
+ SPI_IOC_WR_MODE = 0x40016b01
14
+ SPI_IOC_RD_LSB_FIRST = 0x80016b02
15
+ SPI_IOC_WR_LSB_FIRST = 0x40016b02
16
+ SPI_IOC_RD_BITS_PER_WORD = 0x80016b03
17
+ SPI_IOC_WR_BITS_PER_WORD = 0x40016b03
18
+ SPI_IOC_RD_MAX_SPEED_HZ = 0x80046b04
19
+ SPI_IOC_WR_MAX_SPEED_HZ = 0x40046b04
20
+ SPI_IOC_RD_MODE32 = 0x80046b05
21
+ SPI_IOC_WR_MODE32 = 0x40046b05
22
+
23
+ SPI_IOC_MESSAGE_1 = 0x40206b00 #can only be used to send one spi_ioc_transfer struct at a time
24
+
25
+ SPI_CPHA = 0x01
26
+ SPI_CPOL = 0x02
27
+
28
+ def initialize(polarity: 0, phase: 0, word_size: 8, lsb_first: false)
29
+ @polarity = polarity
30
+ @phase = phase
31
+ @word_size = word_size
32
+ @lsb_first = lsb_first
33
+ @speed_hz = 1000000 #TODO Configurable parameter
34
+
35
+ @device = open("/dev/spidev32766.0", File::RDWR)
36
+
37
+ @mode = 0
38
+ @mode = @mode | 0x01 if (phase == 1)
39
+ @mode = @mode | 0x02 if (polarity == 1)
40
+
41
+ write_u8(SPI_IOC_WR_MODE, @mode)
42
+ write_u8(SPI_IOC_WR_LSB_FIRST, (@lsb_first ? 1 : 0))
43
+ write_u32(SPI_IOC_WR_MAX_SPEED_HZ, @speed_hz)
44
+
45
+ end
46
+
47
+ def close()
48
+ @device.close()
49
+ end
50
+
51
+ def read_u8(msg)
52
+ value_packed = [0].pack("C")
53
+ @device.ioctl(msg, value_packed)
54
+ return value_packed.unpack("C")[0]
55
+ end
56
+
57
+ def write_u8(msg, value)
58
+ value_packed = [value].pack("C")
59
+ @device.ioctl(msg, value_packed)
60
+ end
61
+
62
+ def read_u32(msg)
63
+ value_packed = [0].pack("L")
64
+ @device.ioctl(msg, value_packed)
65
+ return value_packed.unpack("L")[0]
66
+ end
67
+
68
+ def write_u32(msg, value)
69
+ value_packed = [value].pack("L")
70
+ @device.ioctl(msg, value_packed)
71
+ end
72
+
73
+ def break_words_into_nibbles(words: [])
74
+ nibbles_per_word = @word_size / 4
75
+
76
+ #for each word, output each nibble individually
77
+ #(shifting by 4 each time since a nibble is 4 bits)
78
+ words.each do |w|
79
+
80
+ #this is basically the reverse of nibbles_per_word.times
81
+ #we reverse it because we want to start at the most-significant nibble
82
+ #which will be shifted the most times
83
+ #
84
+ #since we want to end up at 0, subtract one from nibbles_per_word
85
+ #so we don't get an extra
86
+ (nibbles_per_word - 1).downto(0).each do |i|
87
+ yield w, ((w >> (i * 4)) & 0xf)
88
+ end
89
+ end
90
+ end
91
+
92
+ def pack_words_into_bytes(words: [])
93
+ nibbles_per_word = @word_size / 4
94
+
95
+ bytes = []
96
+ current_byte = 0
97
+ new_byte = true
98
+
99
+ break_words_into_nibbles(words: words) do |current_word, current_nibble|
100
+ if new_byte
101
+ new_byte = false
102
+ current_byte = current_byte | (current_nibble << 4)
103
+ else
104
+ current_byte = current_byte | current_nibble
105
+
106
+ bytes << current_byte
107
+ current_byte = 0
108
+ new_byte = true
109
+ end
110
+ end
111
+
112
+ return bytes
113
+ end
114
+
115
+ def transfer_bytes(bytes: [])
116
+ # http://stackoverflow.com/questions/11949538/pointers-to-buffer-in-ioctl-call
117
+ raise "Too many bytes sent to transfer_bytes" if bytes.size > SPI_MAX_CHUNK_BYTES
118
+
119
+ #begin spi_ioc_transfer struct (cat /usr/include/linux/spi/spidev.h)
120
+ tx_buff = bytes.pack("C*")
121
+ rx_buff = (Array.new(bytes.size) { 0 }).pack("C*")
122
+
123
+ tx_buff_pointer = [tx_buff].pack("P").unpack("L!")[0] #u64 (zero-extended pointer)
124
+ rx_buff_pointer = [rx_buff].pack("P").unpack("L!")[0] #u64 (zero-extended pointer)
125
+
126
+
127
+ buff_len = bytes.size #u32
128
+ speed_hz = @speed_hz #u32
129
+
130
+ delay_usecs = 0 #u16
131
+ bits_per_word = 8 #u8
132
+ cs_change = 0 #u8
133
+ tx_nbits = 0 #u8
134
+ rx_nbits = 0 #u8
135
+ pad = 0 #u16
136
+
137
+ struct_array = [tx_buff_pointer, rx_buff_pointer, buff_len, speed_hz, delay_usecs, bits_per_word, cs_change, tx_nbits, rx_nbits, pad]
138
+ struct_packed = struct_array.pack("QQLLSCCCCS")
139
+ #end spi_ioc_transfer struct
140
+
141
+ @device.ioctl(SPI_IOC_MESSAGE_1, struct_packed)
142
+
143
+ return rx_buff.unpack("C*")
144
+ end
145
+
146
+ def transfer_data(words: [])
147
+
148
+ bytes_to_transfer = pack_words_into_bytes(words: words)
149
+
150
+ result = []
151
+
152
+ bytes_to_transfer.each_slice(SPI_MAX_CHUNK_BYTES) do |chunk_bytes|
153
+ result = result + transfer_bytes(bytes: chunk_bytes)
154
+ end
155
+
156
+ return result
157
+ end
158
+
159
+ def test()
160
+ words = []
161
+ 24.times { |i| words << 0 }
162
+
163
+ transfer_data(words: words)
164
+ end
165
+
166
+ def to_s
167
+ return "\#<ChipGPIO:HardwareSPI mode=#{@mode} device=#{@device.path} word_size=#{@word_size} lsb_first=#{@lsb_first}>"
168
+ end
169
+ end
170
+ end
@@ -19,7 +19,7 @@
19
19
  # *** Phase
20
20
 
21
21
  module ChipGPIO
22
- class SoftSPI
22
+ class SoftwareSPI
23
23
  attr_reader :clock_pin
24
24
  attr_reader :input_pin
25
25
  attr_reader :output_pin
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chip-gpio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-17 00:00:00.000000000 Z
11
+ date: 2017-01-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A ruby gem to control the IO hardware the CHIP computer
14
14
  email: james@jameswilliams.me
@@ -18,8 +18,9 @@ extra_rdoc_files: []
18
18
  files:
19
19
  - README.md
20
20
  - lib/chip-gpio.rb
21
+ - lib/chip-gpio/HardwareSpi.rb
21
22
  - lib/chip-gpio/Pin.rb
22
- - lib/chip-gpio/SoftSpi.rb
23
+ - lib/chip-gpio/SoftwareSpi.rb
23
24
  homepage: http://github.com/willia4/chip-gpio
24
25
  licenses:
25
26
  - MIT