raudi 0.0.1 → 0.0.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.
- data/.DS_Store +0 -0
- data/.rvmrc +1 -1
- data/bin/raudi +17 -0
- data/configuration/atmega_328.yml +69 -0
- data/configuration/avr.yml +61 -0
- data/lib/.DS_Store +0 -0
- data/lib/raudi.rb +58 -9
- data/lib/raudi/.DS_Store +0 -0
- data/lib/raudi/action_processor.rb +34 -26
- data/lib/raudi/avr.rb +4 -0
- data/lib/raudi/avr/.DS_Store +0 -0
- data/lib/raudi/avr/controller.rb +73 -0
- data/lib/raudi/avr/pin.rb +30 -0
- data/lib/raudi/avr/pin_states.rb +73 -0
- data/lib/raudi/avr/port.rb +36 -0
- data/lib/raudi/avr/timer.rb +49 -0
- data/lib/raudi/core_ext.rb +1 -0
- data/lib/raudi/core_ext/fixnum.rb +16 -0
- data/lib/raudi/info.rb +52 -0
- data/lib/raudi/processing.rb +63 -0
- data/lib/raudi/processing/gpio.rb +25 -0
- data/lib/raudi/processing/int.rb +36 -0
- data/lib/raudi/processing/pcint.rb +35 -0
- data/lib/raudi/processing/timer.rb +56 -0
- data/lib/raudi/proxy/.DS_Store +0 -0
- data/lib/raudi/proxy/controller.rb +65 -0
- data/lib/raudi/proxy/external_interrupt.rb +30 -0
- data/lib/raudi/proxy/gpio.rb +19 -0
- data/lib/raudi/proxy/headers.rb +31 -0
- data/lib/raudi/proxy/timer.rb +61 -0
- data/lib/raudi/source.rb +48 -0
- data/lib/raudi/source/action.rb +16 -0
- data/lib/raudi/source/bit_operations.rb +35 -0
- data/lib/raudi/source/block.rb +44 -0
- data/lib/raudi/source/controller.rb +56 -0
- data/lib/raudi/source/function.rb +50 -0
- data/lib/raudi/source/interrupt.rb +35 -0
- data/lib/raudi/source/variable.rb +31 -0
- data/lib/raudi/state_list.rb +17 -0
- data/raudi.gemspec +3 -0
- data/spec/.DS_Store +0 -0
- data/spec/examples/sample.raudi +5 -0
- data/spec/lib/.DS_Store +0 -0
- data/spec/lib/raudi/.DS_Store +0 -0
- data/spec/lib/raudi/action_processor_spec.rb +35 -0
- data/spec/lib/raudi/avr/controller_spec.rb +13 -0
- data/spec/lib/raudi/avr/pin_spec.rb +70 -0
- data/spec/lib/raudi/avr/timer_spec.rb +22 -0
- data/spec/lib/raudi/info_spec.rb +9 -0
- data/spec/lib/raudi/proxy/external_interrupt_spec.rb +22 -0
- data/spec/lib/raudi/proxy/gpio_spec.rb +18 -0
- data/spec/lib/raudi/proxy/headers_spec.rb +34 -0
- data/spec/lib/raudi/proxy/timer_spec.rb +67 -0
- data/spec/lib/raudi/source/external_interrupt_spec.rb +55 -0
- data/spec/lib/raudi/source/gpio_spec.rb +18 -0
- data/spec/lib/raudi/source/main_structure_spec.rb +19 -0
- data/spec/lib/raudi/source/timer_spec.rb +44 -0
- data/spec/lib/raudi_spec.rb +41 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/raudi_spec_helper.rb +27 -0
- metadata +106 -19
- data/examples/actions.raudi +0 -1
- data/examples/config.rb +0 -3
- data/examples/result.c +0 -10
- data/lib/raudi/avr_controller.rb +0 -23
- data/spec/raudi_spec.rb +0 -9
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'raudi/state_list'
|
2
|
+
|
3
|
+
module Raudi
|
4
|
+
|
5
|
+
module AVR
|
6
|
+
|
7
|
+
class Port
|
8
|
+
|
9
|
+
include StateList
|
10
|
+
|
11
|
+
attr_accessor :name, :pins, :interrupts, :pc_number
|
12
|
+
|
13
|
+
def initialize(name, config)
|
14
|
+
self.name = name.upcase
|
15
|
+
self.pins = config['pins'].map{|pin_number, types| Pin.new(self, pin_number, types)}
|
16
|
+
self.pc_number= config['pc_number']
|
17
|
+
self.interrupts = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_interrupt(new_interrupt)
|
21
|
+
self.interrupts << new_interrupt unless interrupts.include?(new_interrupt)
|
22
|
+
end
|
23
|
+
|
24
|
+
def pins(pin_number = nil)
|
25
|
+
if pin_number
|
26
|
+
@pins.detect{|pin| pin.number == pin_number.to_i}
|
27
|
+
else
|
28
|
+
@pins
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module AVR
|
4
|
+
|
5
|
+
class Timer
|
6
|
+
|
7
|
+
attr_accessor :active, :counter, :interrupt, :mode, :mode_params, :name, :length, :prescale
|
8
|
+
|
9
|
+
[:normal, :ctc].each do |timer_mode|
|
10
|
+
define_method("#{timer_mode}?") do
|
11
|
+
self.mode == timer_mode
|
12
|
+
end
|
13
|
+
|
14
|
+
define_method("#{timer_mode}!") do
|
15
|
+
self.mode = timer_mode
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(name, params)
|
20
|
+
self.name = name
|
21
|
+
self.length = params['length']
|
22
|
+
self.normal!
|
23
|
+
end
|
24
|
+
|
25
|
+
def number
|
26
|
+
name[/\d+/].to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
def range
|
30
|
+
0...max_number
|
31
|
+
end
|
32
|
+
|
33
|
+
def max_number
|
34
|
+
2**length
|
35
|
+
end
|
36
|
+
|
37
|
+
def mode=(new_mode)
|
38
|
+
if @mode != new_mode
|
39
|
+
@mode = new_mode
|
40
|
+
self.mode_params = {}
|
41
|
+
self.interrupt = nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'raudi/core_ext/fixnum'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Fixnum.class_eval do
|
2
|
+
|
3
|
+
def to_bits(length, options = {})
|
4
|
+
if prefix = options[:prefix]
|
5
|
+
length.times.inject([]) do |list, index|
|
6
|
+
if self[index] == 1
|
7
|
+
list << "#{prefix}#{index}"
|
8
|
+
end
|
9
|
+
list
|
10
|
+
end
|
11
|
+
else
|
12
|
+
length.times.map{ |index| self[index] == 1 }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/lib/raudi/info.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module Info
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def config
|
8
|
+
@config ||= begin
|
9
|
+
path = File.join(File.dirname(__FILE__), '../../', 'configuration/avr.yml')
|
10
|
+
YAML.load_file(path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method_name, *args)
|
15
|
+
if result = config[method_name.to_s]
|
16
|
+
result
|
17
|
+
else
|
18
|
+
super(method_name, *args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def pin_states
|
23
|
+
gpio_states + specific_pin_states
|
24
|
+
end
|
25
|
+
|
26
|
+
def headers
|
27
|
+
@headers ||= begin
|
28
|
+
list = []
|
29
|
+
config['headers'].each do |namespace, headers|
|
30
|
+
list += headers.map{|header| "#{process_namespace(namespace)}#{header}"}
|
31
|
+
end
|
32
|
+
list
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def interrupt_event(event_name)
|
37
|
+
list = config['interrupts']['events'][event_name.to_s]
|
38
|
+
raise "Undefined interrupt event - #{event_name}" unless list.is_a?(Fixnum)
|
39
|
+
list
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def process_namespace(name)
|
45
|
+
(name == 'common') ? '' : name + '/'
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module Processing
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
attr_accessor :list
|
8
|
+
|
9
|
+
def list
|
10
|
+
@list ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class Base
|
16
|
+
|
17
|
+
attr_accessor :controller, :source
|
18
|
+
|
19
|
+
def self.inherited(klass)
|
20
|
+
Processing.list << klass
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(controller, source)
|
24
|
+
self.controller = controller
|
25
|
+
self.source = source
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_interrupts
|
29
|
+
return unless can_process?
|
30
|
+
interrupts
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_config
|
34
|
+
return unless can_process?
|
35
|
+
config
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(method_name, *args, &block)
|
39
|
+
[source, controller].each do |delegate|
|
40
|
+
return delegate.send(method_name, *args, &block) if delegate.respond_to?(method_name)
|
41
|
+
end
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def interrupts
|
48
|
+
end
|
49
|
+
|
50
|
+
def config
|
51
|
+
end
|
52
|
+
|
53
|
+
def can_process?
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
Dir[File.dirname(__FILE__) + '/processing/*.rb'].each{ |file_name| require file_name }
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module Processing
|
4
|
+
|
5
|
+
class GPIO < Base
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def config
|
10
|
+
ports.each do |port|
|
11
|
+
register_name = "DDR#{port.name}"
|
12
|
+
bits = port.output_pins.map(&:number)
|
13
|
+
write_register(register_name, bits)
|
14
|
+
|
15
|
+
register_name = "PORT#{port.name}"
|
16
|
+
bits = port.pullup_pins.map(&:number)
|
17
|
+
write_register(register_name, bits)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module Processing
|
4
|
+
|
5
|
+
class Int < Base
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def interrupts
|
10
|
+
int_pins.each do |pin|
|
11
|
+
interrupt_block pin.to_c
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def config
|
16
|
+
register_name = "EICRA"
|
17
|
+
bits = []
|
18
|
+
int_pins.each do |pin|
|
19
|
+
bits += Info.interrupt_event(pin.state_params).to_bits(2, :prefix => "ISC#{pin.state_number}")
|
20
|
+
end
|
21
|
+
write_register(register_name, bits)
|
22
|
+
|
23
|
+
register_name = "EIMSK"
|
24
|
+
bits = int_pins.map(&:to_c)
|
25
|
+
write_register(register_name, bits)
|
26
|
+
end
|
27
|
+
|
28
|
+
def can_process?
|
29
|
+
int_present?
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module Processing
|
4
|
+
|
5
|
+
class PCInt < Base
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def interrupts
|
10
|
+
ports.each do |port|
|
11
|
+
next unless port.pcint_present?
|
12
|
+
interrupt_block "PCINT#{port.pc_number}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
pc_ports = []
|
18
|
+
ports.map do |port|
|
19
|
+
next unless port.pcint_present?
|
20
|
+
register_name = "PCMSK#{port.pc_number}"
|
21
|
+
bits = port.pcint_pins.map(&:to_c)
|
22
|
+
write_register(register_name, bits)
|
23
|
+
|
24
|
+
pc_ports << "PCIE#{port.pc_number}"
|
25
|
+
end
|
26
|
+
|
27
|
+
register_name = "PCICR"
|
28
|
+
write_register(register_name, pc_ports)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Raudi
|
2
|
+
|
3
|
+
module Processing
|
4
|
+
|
5
|
+
class Timer < Base
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def active_timers
|
10
|
+
timers.select(&:active)
|
11
|
+
end
|
12
|
+
|
13
|
+
def config
|
14
|
+
active_timers.each do |timer|
|
15
|
+
set_timer_mask(timer)
|
16
|
+
set_mode(timer)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def interrupts
|
21
|
+
active_timers.each do |timer|
|
22
|
+
next unless timer.interrupt
|
23
|
+
prefix = "timer#{timer.number}"
|
24
|
+
case
|
25
|
+
when timer.normal?
|
26
|
+
interrupt_block(prefix, "ovf")
|
27
|
+
when timer.ctc?
|
28
|
+
timer.mode_params.keys.each do |register_name|
|
29
|
+
interrupt_block(prefix, "comp#{register_name}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_mode(timer)
|
36
|
+
register_name = "TCCR#{timer.number}B"
|
37
|
+
bits = timer.prescale.to_bits(3, :prefix => "CS#{timer.number}")
|
38
|
+
bits << "WGM#{timer.number}2" if timer.ctc?
|
39
|
+
write_register(register_name, bits)
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_timer_mask(timer)
|
43
|
+
return unless timer.interrupt
|
44
|
+
case
|
45
|
+
when timer.normal?
|
46
|
+
register_name = "TIMSK#{timer.number}"
|
47
|
+
bits = ["TOIE#{timer.number}"]
|
48
|
+
write_register(register_name, bits)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
Binary file
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'raudi/proxy/external_interrupt'
|
2
|
+
require 'raudi/proxy/gpio'
|
3
|
+
require 'raudi/proxy/headers'
|
4
|
+
require 'raudi/proxy/timer'
|
5
|
+
|
6
|
+
module Raudi
|
7
|
+
|
8
|
+
module Proxy
|
9
|
+
|
10
|
+
class Controller
|
11
|
+
|
12
|
+
include ExternalInterrupt
|
13
|
+
include GPIO
|
14
|
+
include Headers
|
15
|
+
include Timer
|
16
|
+
|
17
|
+
attr_accessor :controller
|
18
|
+
|
19
|
+
def initialize(controller, &block)
|
20
|
+
self.controller = controller
|
21
|
+
instance_eval(&block) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def get_pin(pin_name)
|
27
|
+
port_name = pin_name[/[a-z]+/i]
|
28
|
+
raise "Port is not specified" unless port_name
|
29
|
+
pin_number = pin_name[/\d+/]
|
30
|
+
raise "Pin is not specified" unless pin_number
|
31
|
+
port = controller.ports(port_name)
|
32
|
+
raise "Port #{port_name} doesn't exists in controller" unless port
|
33
|
+
pin = port.pins(pin_number)
|
34
|
+
raise "Pin #{pin_number} doesn't exists in port #{port_name}" unless pin
|
35
|
+
pin
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(method_name, *args)
|
39
|
+
if controller.respond_to?("#{method_name}=")
|
40
|
+
controller.send("#{method_name}=", *args)
|
41
|
+
else
|
42
|
+
raise "Illegal property #{method_name}, check configuration file"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def set_interrupt(*args)
|
47
|
+
headers :interrupt
|
48
|
+
controller.interrupt = true
|
49
|
+
return if args.empty? or !block_given?
|
50
|
+
args.each do |arg|
|
51
|
+
yield arg
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_pin_mode(*args, &block)
|
56
|
+
args.each do |arg|
|
57
|
+
block.call(get_pin(arg))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|