bcm2835 0.0.1
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.
- data/.gitignore +17 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +111 -0
- data/Rakefile +10 -0
- data/bcm2835.gemspec +20 -0
- data/lib/bcm2835.rb +27 -0
- data/lib/bcm2835/gpio.rb +123 -0
- data/lib/bcm2835/native.rb +38 -0
- data/lib/bcm2835/spi.rb +245 -0
- data/lib/bcm2835/version.rb +3 -0
- metadata +89 -0
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--exclude lib/bcm2835/native.rb
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
# Ruby Bindings for [libbcm2835](http://www.open.com.au/mikem/bcm2835/)
|
2
|
+
|
3
|
+
The BCM2835 is the ARM11 core used in the Raspberry PI. It exposes several harware peripherals:
|
4
|
+
|
5
|
+
- [GPIO](#gpio)
|
6
|
+
- [SPI](#spi)
|
7
|
+
- [I²C](#i%C2%B2c)
|
8
|
+
- [UART](#uart)
|
9
|
+
|
10
|
+
This library is a wrapper on top of [libbcm2835](http://www.open.com.au/mikem/bcm2835/) that provides a high level interface for accessing the ARM's hardware features from Ruby
|
11
|
+
|
12
|
+
**[View the Full Documentation on rubydoc.info](http://rubydoc.info/github/joshnuss/bcm2835/master/frames)**
|
13
|
+
|
14
|
+
## GPIO
|
15
|
+
|
16
|
+
[General Purpose Input/Output](http://en.wikipedia.org/wiki/GPIO)
|
17
|
+
|
18
|
+
### Using Inputs
|
19
|
+
```ruby
|
20
|
+
pin = 17
|
21
|
+
|
22
|
+
# make pin an input
|
23
|
+
GPIO.input(pin)
|
24
|
+
|
25
|
+
# check if the input is HIGH i.e. true
|
26
|
+
puts "door is closed" if GPIO[pin]
|
27
|
+
```
|
28
|
+
|
29
|
+
### Using Outputs
|
30
|
+
```ruby
|
31
|
+
pin = 17
|
32
|
+
|
33
|
+
# make pin an output
|
34
|
+
GPIO.output(pin)
|
35
|
+
|
36
|
+
# blink
|
37
|
+
loop do
|
38
|
+
GPIO[pin] = true
|
39
|
+
sleep(1)
|
40
|
+
GPIO[pin] = false
|
41
|
+
sleep(1)
|
42
|
+
end
|
43
|
+
```
|
44
|
+
## SPI
|
45
|
+
|
46
|
+
[Serial Peripheral Interface](http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus)
|
47
|
+
|
48
|
+
### Reading from the SPI bus
|
49
|
+
```ruby
|
50
|
+
SPI.begin do |spi|
|
51
|
+
puts spi.read # returns 1 byte
|
52
|
+
puts spi.read(1024) # returns an array of 1024 bytes
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
### Writing to the SPI bus
|
57
|
+
```ruby
|
58
|
+
SPI.begin do |spi|
|
59
|
+
spi.write(0x22) # write 1 byte
|
60
|
+
spi.write("hello") # write 5 bytes
|
61
|
+
spi.write(0x22,0x45,0x71) # write several bytes at once
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
## I²C
|
66
|
+
|
67
|
+
[Two Wire Interface](http://en.wikipedia.org/wiki/I²C)
|
68
|
+
|
69
|
+
Not yet implemented
|
70
|
+
|
71
|
+
## UART
|
72
|
+
|
73
|
+
[Universal Asynchronous Receiver/Transmitter](http://en.wikipedia.org/wiki/UART)
|
74
|
+
|
75
|
+
You can use the Ruby Standard Library to read and write from the UART
|
76
|
+
|
77
|
+
### Echo Example
|
78
|
+
```ruby
|
79
|
+
File.open('/dev/ttyAMA0', 'a+') do |file|
|
80
|
+
loop do
|
81
|
+
data = file.read
|
82
|
+
file.puts(data)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
## Installation
|
88
|
+
|
89
|
+
Add this line to your application's Gemfile:
|
90
|
+
|
91
|
+
gem 'bcm2835'
|
92
|
+
|
93
|
+
And then execute:
|
94
|
+
|
95
|
+
$ bundle
|
96
|
+
|
97
|
+
Or install it yourself as:
|
98
|
+
|
99
|
+
$ gem install bcm2835
|
100
|
+
|
101
|
+
## Usage
|
102
|
+
|
103
|
+
TODO: Write usage instructions here
|
104
|
+
|
105
|
+
## Contributing
|
106
|
+
|
107
|
+
1. Fork it
|
108
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
109
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
110
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
111
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bcm2835.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/bcm2835/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = "Joshua Nussbaum"
|
6
|
+
gem.email = "joshnuss@gmail.com"
|
7
|
+
gem.description = %q{Bindings for libbcm2385}
|
8
|
+
gem.summary = %q{}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "bcm2835"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Bcm2835::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "ffi"
|
19
|
+
gem.add_development_dependency "rspec"
|
20
|
+
end
|
data/lib/bcm2835.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "bcm2835/version"
|
2
|
+
require "bcm2835/native"
|
3
|
+
require "bcm2835/gpio"
|
4
|
+
require "bcm2835/spi"
|
5
|
+
|
6
|
+
# Provides access to library initialization and shutdown
|
7
|
+
module Bcm2835
|
8
|
+
|
9
|
+
# Initialize the native library
|
10
|
+
#
|
11
|
+
# @return [Boolean] true if the library was opened successfully
|
12
|
+
def init
|
13
|
+
raise Errno::EACCES.new unless Native.init == 1
|
14
|
+
end
|
15
|
+
|
16
|
+
# Close the native library
|
17
|
+
#
|
18
|
+
# @return [Boolean] true if the library was closed successfully
|
19
|
+
def close
|
20
|
+
Native.close == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
module_function :init, :close
|
24
|
+
end
|
25
|
+
|
26
|
+
at_exit { Bcm2835.close }
|
27
|
+
Bcm2835.init
|
data/lib/bcm2835/gpio.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
module Bcm2835
|
2
|
+
# Provides access to the CPU's General Purpose I/Os
|
3
|
+
module GPIO
|
4
|
+
|
5
|
+
# Configures the direction of a pin as either an input or an output
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# button_pin = 17
|
9
|
+
# led_pin = 16
|
10
|
+
#
|
11
|
+
# GPIO.direction(button_pin, :input)
|
12
|
+
# GPIO.direction(led_pin, :output)
|
13
|
+
#
|
14
|
+
# @param [Number] pin the id of the pin
|
15
|
+
# @param [Symbol] mode the direction of the pin, either :input or :output
|
16
|
+
def direction(pin, mode)
|
17
|
+
case mode
|
18
|
+
when :input
|
19
|
+
input(pin)
|
20
|
+
when :output
|
21
|
+
output(pin)
|
22
|
+
else
|
23
|
+
raise ArgumentError.new("Mode #{mode} is invalid. Use :input or :output")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Configures a pin as input
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# pin = 17
|
31
|
+
# GPIO.input(pin)
|
32
|
+
#
|
33
|
+
# @param [Number] pin the id of the pin
|
34
|
+
def input(pin)
|
35
|
+
Native.gpio_function(pin, Native::GPIO_FSEL_INPT)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Configures a pin as output
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# pin = 17
|
42
|
+
# GPIO.output(pin)
|
43
|
+
#
|
44
|
+
# @param [Number] pin the id of the pin
|
45
|
+
def output(pin)
|
46
|
+
Native.gpio_function(pin, Native::GPIO_FSEL_OUTP)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Sets an output pin to HIGH
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# pin = 17
|
53
|
+
#
|
54
|
+
# GPIO.output(pin)
|
55
|
+
# GPIO.set(pin) # make pin HIGH
|
56
|
+
#
|
57
|
+
# @param [Number] pin the id of the pin
|
58
|
+
def set(pin)
|
59
|
+
Native.gpio_set(pin)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Clears an output pin to LOW
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# pin = 17
|
66
|
+
#
|
67
|
+
# GPIO.output(pin)
|
68
|
+
# GPIO.clear(pin) # make pin LOW
|
69
|
+
#
|
70
|
+
# @param [Number] pin the id of the pin
|
71
|
+
def clear(pin)
|
72
|
+
Native.gpio_clear(pin)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Sets or clears an output pin
|
76
|
+
#
|
77
|
+
# @example Using indexer (preferred)
|
78
|
+
# pin = 17
|
79
|
+
#
|
80
|
+
# GPIO.output(pin)
|
81
|
+
# GPIO[pin] = true # make pin HIGH
|
82
|
+
# GPIO[pin] = false # make pin LOW
|
83
|
+
#
|
84
|
+
# @example Using write
|
85
|
+
# pin = 17
|
86
|
+
#
|
87
|
+
# GPIO.output(pin)
|
88
|
+
# GPIO.write(pin, true) # make pin HIGH
|
89
|
+
# GPIO.write(pin, false) # make pin LOW
|
90
|
+
#
|
91
|
+
# @param [Number] pin the id of the pin
|
92
|
+
# @param [Boolean] value true sets the pin HIGH, false sets the pin LOW
|
93
|
+
def write(pin, value)
|
94
|
+
value ? set(pin) : clear(pin)
|
95
|
+
end
|
96
|
+
|
97
|
+
alias :[]= :write
|
98
|
+
|
99
|
+
# Reads an input pin
|
100
|
+
#
|
101
|
+
# @example Using indexer (preferred)
|
102
|
+
# pin = 17
|
103
|
+
#
|
104
|
+
# GPIO.input(pin)
|
105
|
+
# puts GPIO[pin]
|
106
|
+
#
|
107
|
+
# @example Using read
|
108
|
+
# pin = 17
|
109
|
+
#
|
110
|
+
# GPIO.input(pin)
|
111
|
+
# puts GPIO.read(pin)
|
112
|
+
#
|
113
|
+
# @param [Number] pin the id of the pin
|
114
|
+
# @return [Boolean] true if the pin is HIGH, false if the pin is LOW
|
115
|
+
def read(pin)
|
116
|
+
Native.gpio_level(pin) == Native::HIGH
|
117
|
+
end
|
118
|
+
|
119
|
+
alias :[] :read
|
120
|
+
|
121
|
+
module_function :direction, :input, :output, :set, :clear, :read, :write, :[], :[]=
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Bcm2835
|
4
|
+
module Native
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib '/usr/local/lib/libbcm2835.so'
|
7
|
+
|
8
|
+
GPIO_FSEL_INPT = 0b000
|
9
|
+
GPIO_FSEL_OUTP = 0b001
|
10
|
+
GPIO_FSEL_ALT0 = 0b100
|
11
|
+
GPIO_FSEL_ALT1 = 0b101
|
12
|
+
GPIO_FSEL_ALT2 = 0b110
|
13
|
+
GPIO_FSEL_ALT3 = 0b111
|
14
|
+
GPIO_FSEL_ALT4 = 0b011
|
15
|
+
GPIO_FSEL_ALT5 = 0b010
|
16
|
+
GPIO_FSEL_MASK = 0b111
|
17
|
+
|
18
|
+
LOW = 0
|
19
|
+
HIGH = 1
|
20
|
+
|
21
|
+
attach_function :init, :bcm2835_init, [], :uint8
|
22
|
+
attach_function :close, :bcm2835_close, [], :uint8
|
23
|
+
|
24
|
+
attach_function :gpio_function, :bcm2835_gpio_fsel, [:uint8, :uint8], :void
|
25
|
+
attach_function :gpio_set, :bcm2835_gpio_set, [:uint8], :void
|
26
|
+
attach_function :gpio_clear, :bcm2835_gpio_clr, [:uint8], :void
|
27
|
+
attach_function :gpio_level, :bcm2835_gpio_lev, [:uint8], :uint8
|
28
|
+
|
29
|
+
attach_function :spi_begin, :bcm2835_spi_begin, [], :uint8
|
30
|
+
attach_function :spi_end, :bcm2835_spi_end, [], :uint8
|
31
|
+
attach_function :spi_transfer, :bcm2835_spi_transfer, [:uint8], :uint8
|
32
|
+
attach_function :spi_clock, :bcm2835_spi_setClockDivider, [:uint8], :void
|
33
|
+
attach_function :spi_bit_order, :bcm2835_spi_setBitOrder, [:uint8], :void
|
34
|
+
attach_function :spi_chip_select, :bcm2835_spi_chipSelect, [:uint8], :void
|
35
|
+
attach_function :spi_chip_select_polarity,
|
36
|
+
:bcm2835_spi_setChipSelectPolarity, [:uint8, :uint8], :void
|
37
|
+
end
|
38
|
+
end
|
data/lib/bcm2835/spi.rb
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
module Bcm2835
|
2
|
+
# Provides access to the Serial Peripheral Interface Bus
|
3
|
+
class SPI
|
4
|
+
# 65536 = 256us = 4kHz
|
5
|
+
CLOCK_DIVIDER_65536 = 0
|
6
|
+
# 32768 = 126us = 8kHz
|
7
|
+
CLOCK_DIVIDER_32768 = 32768
|
8
|
+
# 16384 = 64us = 15.625kHz
|
9
|
+
CLOCK_DIVIDER_16384 = 16384
|
10
|
+
# 8192 = 32us = 31.25kHz
|
11
|
+
CLOCK_DIVIDER_8192 = 8192
|
12
|
+
# 4096 = 16us = 62.5kHz
|
13
|
+
CLOCK_DIVIDER_4096 = 4096
|
14
|
+
# 2048 = 8us = 125kHz
|
15
|
+
CLOCK_DIVIDER_2048 = 2048
|
16
|
+
# 1024 = 4us = 250kHz
|
17
|
+
CLOCK_DIVIDER_1024 = 1024
|
18
|
+
# 512 = 2us = 500kHz
|
19
|
+
CLOCK_DIVIDER_512 = 512
|
20
|
+
# 256 = 1us = 1MHz
|
21
|
+
CLOCK_DIVIDER_256 = 256
|
22
|
+
# 128 = 500ns = = 2MHz
|
23
|
+
CLOCK_DIVIDER_128 = 128
|
24
|
+
# 64 = 250ns = 4MHz
|
25
|
+
CLOCK_DIVIDER_64 = 64
|
26
|
+
# 32 = 125ns = 8MHz
|
27
|
+
CLOCK_DIVIDER_32 = 32
|
28
|
+
# 16 = 50ns = 20MHz
|
29
|
+
CLOCK_DIVIDER_16 = 16
|
30
|
+
|
31
|
+
# Least signifigant bit first, e.g. 4 = 0b001
|
32
|
+
LSBFIRST = 0
|
33
|
+
# Most signifigant bit first, e.g. 4 = 0b100
|
34
|
+
MSBFIRST = 1
|
35
|
+
|
36
|
+
# Select Chip 0
|
37
|
+
CHIP_SELECT_0 = 0
|
38
|
+
# Select Chip 1
|
39
|
+
CHIP_SELECT_1 = 1
|
40
|
+
# Select both chips (ie pins CS1 and CS2 are asserted)
|
41
|
+
CHIP_SELECT_BOTH = 2
|
42
|
+
# No CS, control it yourself
|
43
|
+
CHIP_SELECT_NONE = 3
|
44
|
+
|
45
|
+
# Initializes SPI, must be called before SPI can be used
|
46
|
+
#
|
47
|
+
# @example With a block
|
48
|
+
# SPI.begin do |spi|
|
49
|
+
# spi.write 1
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# @example Without a block
|
53
|
+
# spi = SPI.begin
|
54
|
+
# spi.write 1
|
55
|
+
# spi.end # must call end yourself
|
56
|
+
#
|
57
|
+
# @example Specifying the chip select line
|
58
|
+
# SPI.begin(SPI::CHIP_SELECT_1) do |spi|
|
59
|
+
# spi.write 1
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# @yield [SPI]
|
63
|
+
# @param [optional, CHIP_SELECT_*] chip defaults to CHIP_SELECT_0
|
64
|
+
# @return [SPI]
|
65
|
+
def self.begin(chip=nil)
|
66
|
+
Native.spi_begin
|
67
|
+
chip = CHIP_SELECT_0 if !chip && block_given?
|
68
|
+
spi = new(chip)
|
69
|
+
|
70
|
+
if block_given?
|
71
|
+
begin
|
72
|
+
yield(spi)
|
73
|
+
ensure
|
74
|
+
self.end
|
75
|
+
end
|
76
|
+
else
|
77
|
+
spi
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Manually shut down SPI
|
82
|
+
#
|
83
|
+
# Not needed when #begin is called with a block
|
84
|
+
def self.end
|
85
|
+
Native.spi_end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Configure the clock prescaler
|
89
|
+
#
|
90
|
+
# Default is CLOCK_DIVIDER_65536 (4kHz)
|
91
|
+
#
|
92
|
+
# @example Run SPI at 2MHz
|
93
|
+
# spi.clock(SPI::CLOCK_DIVIDER_128)
|
94
|
+
#
|
95
|
+
# @param [CLOCK_DIVIDER_*] divider the value to prescale the clock by
|
96
|
+
def clock(divider)
|
97
|
+
Native.spi_clock(divider)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Configure the order that bits are sent and received from the bus
|
101
|
+
#
|
102
|
+
# @example Most signifigant bit first
|
103
|
+
# spi.bit_order(7..0)
|
104
|
+
# # or
|
105
|
+
# spi.bit_order(SPI::MSBFIRST)
|
106
|
+
#
|
107
|
+
# @example Least signifigant bit first
|
108
|
+
# spi.bit_order(0..7)
|
109
|
+
# # or
|
110
|
+
# spi.bit_order(SPI::LSBFIRST)
|
111
|
+
#
|
112
|
+
# @param [Range|LSBFIRST|MSBFIRST] order
|
113
|
+
def bit_order(order=MSBFIRST)
|
114
|
+
if order.is_a?(Range)
|
115
|
+
if order.begin < order.end
|
116
|
+
order = LSBFIRST
|
117
|
+
else
|
118
|
+
order = MSBFIRST
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
Native.spi_bit_order(order)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Activate a specific chip so that communication can begin
|
126
|
+
#
|
127
|
+
# When a block is provided, the chip is automatically deactivated after the block completes.
|
128
|
+
# When a block is not provided, the user is responsible for calling chip_select(CHIP_SELECT_NONE)
|
129
|
+
#
|
130
|
+
# @example With block (preferred)
|
131
|
+
# spi.chip_select do
|
132
|
+
# spi.write(0xFF)
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# @example Without block
|
136
|
+
# spi.chip_select(CHIP_SELECT_0)
|
137
|
+
# spi.write(0xFF)
|
138
|
+
# spi.write(0x22)
|
139
|
+
# spi.chip_select(CHIP_SELECT_NONE)
|
140
|
+
#
|
141
|
+
# @yield
|
142
|
+
# @param [optional, CHIP_SELECT_*] chip the chip select line options
|
143
|
+
def chip_select(chip=CHIP_SELECT_0)
|
144
|
+
chip = @chip if @chip
|
145
|
+
Native.spi_chip_select(chip)
|
146
|
+
if block_given?
|
147
|
+
begin
|
148
|
+
yield
|
149
|
+
ensure
|
150
|
+
Native.spi_chip_select(CHIP_SELECT_NONE)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Configure the active state of the chip select line
|
156
|
+
#
|
157
|
+
# The default state for most chips is active low.
|
158
|
+
#
|
159
|
+
# "active low" means the clock line is kept high during idle, and goes low when communicating.
|
160
|
+
#
|
161
|
+
# "active high" means the clock line is kept low during idle, and goes high when communicating.
|
162
|
+
#
|
163
|
+
# @param [Boolean] active_low true for active low, false for active high
|
164
|
+
# @param [optional, CHIP_SELECT_*] chip one of CHIP_SELECT_*
|
165
|
+
def chip_select_active_low(active_low, chip=nil)
|
166
|
+
chip = @chip if @chip
|
167
|
+
chip = CHIP_SELECT_0 unless chip
|
168
|
+
|
169
|
+
Native.spi_chip_select_polarity(chip, active_low ? Native::LOW : Native::HIGH)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Read from the bus
|
173
|
+
#
|
174
|
+
# @example Read a single byte
|
175
|
+
# byte = spi.read
|
176
|
+
#
|
177
|
+
# @example Read array of bytes
|
178
|
+
# array = spi.read(3)
|
179
|
+
#
|
180
|
+
#
|
181
|
+
# @param [optional, Number] count the number of bytes to read.
|
182
|
+
# When count is provided, an array is returned.
|
183
|
+
# When count is nil, a single byte is returned.
|
184
|
+
# @return [Number|Array] data that was read from the bus
|
185
|
+
def read(count=nil)
|
186
|
+
if count
|
187
|
+
write([0xFF] * count)
|
188
|
+
else
|
189
|
+
enable { Native.spi_transfer(0) }
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Write to the bus
|
194
|
+
#
|
195
|
+
# @example Write a single byte
|
196
|
+
# spi.write(0x22)
|
197
|
+
#
|
198
|
+
# @example Write multiple bytes
|
199
|
+
# spi.write(0x22, 0x33, 0x44)
|
200
|
+
#
|
201
|
+
# @example Write a string
|
202
|
+
# spi.write("Hello SPI!")
|
203
|
+
#
|
204
|
+
# @example Write any enumerable
|
205
|
+
# spi.write(30..40)
|
206
|
+
#
|
207
|
+
# @return [Number|Array|String] data that came out of MISO during write
|
208
|
+
def write(*args)
|
209
|
+
case args.count
|
210
|
+
when 0
|
211
|
+
raise ArgumentError.new("missing arguments")
|
212
|
+
when 1
|
213
|
+
data = args.first
|
214
|
+
else
|
215
|
+
data = args
|
216
|
+
end
|
217
|
+
|
218
|
+
enable do
|
219
|
+
case data
|
220
|
+
when Numeric
|
221
|
+
Native.spi_transfer(data)
|
222
|
+
when String
|
223
|
+
data.each_byte.map {|byte| Native.spi_transfer(byte).chr }.join
|
224
|
+
when Enumerable
|
225
|
+
data.map {|byte| Native.spi_transfer(byte) }
|
226
|
+
else
|
227
|
+
raise ArgumentError.new("#{data.class} is not valid data. User Numeric, String or an Enumerable of numbers")
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
private
|
233
|
+
def initialize(chip)
|
234
|
+
@chip = chip
|
235
|
+
end
|
236
|
+
|
237
|
+
def enable(&block)
|
238
|
+
if @chip
|
239
|
+
chip_select(&block)
|
240
|
+
else
|
241
|
+
yield
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bcm2835
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Joshua Nussbaum
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ffi
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Bindings for libbcm2385
|
47
|
+
email: joshnuss@gmail.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- .gitignore
|
53
|
+
- .yardopts
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- bcm2835.gemspec
|
59
|
+
- lib/bcm2835.rb
|
60
|
+
- lib/bcm2835/gpio.rb
|
61
|
+
- lib/bcm2835/native.rb
|
62
|
+
- lib/bcm2835/spi.rb
|
63
|
+
- lib/bcm2835/version.rb
|
64
|
+
homepage: ''
|
65
|
+
licenses: []
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.24
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: ''
|
88
|
+
test_files: []
|
89
|
+
has_rdoc:
|