chip-gpio 0.0.6 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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