madrona-rad 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +10 -0
- data/Manifest.txt +26 -0
- data/bin/rad +28 -36
- data/lib/examples/blink_m_hello.rb +14 -0
- data/lib/examples/debounce_methods.rb +49 -0
- data/lib/examples/external_variable_fu.rb +24 -0
- data/lib/examples/external_variables.rb +31 -0
- data/lib/examples/hello_eeprom.rb +54 -0
- data/lib/examples/i2c_with_clock_chip.rb +124 -0
- data/lib/examples/two_wire.rb +14 -0
- data/lib/libraries/DS1307/DS1307.cpp +161 -0
- data/lib/libraries/DS1307/DS1307.h +64 -0
- data/lib/libraries/DS1307/keywords.txt +18 -0
- data/lib/libraries/OneWire/OneWire.cpp +194 -0
- data/lib/libraries/OneWire/OneWire.h +63 -0
- data/lib/libraries/OneWire/keywords.txt +35 -0
- data/lib/libraries/OneWire/readme.txt +13 -0
- data/lib/libraries/Wire/Wire.cpp +262 -0
- data/lib/libraries/Wire/Wire.h +67 -0
- data/lib/libraries/Wire/keywords.txt +31 -0
- data/lib/libraries/Wire/twi.h +57 -0
- data/lib/plugins/bitwise_ops.rb +54 -0
- data/lib/plugins/blink_m.rb +304 -6
- data/lib/plugins/debounce.rb +46 -24
- data/lib/plugins/i2c_eeprom.rb +70 -0
- data/lib/rad/arduino_plugin.rb +27 -4
- data/lib/rad/arduino_sketch.rb +354 -115
- data/lib/rad/generators/makefile/makefile.erb +2 -2
- data/lib/rad/generators/makefile/makefile.rb +5 -9
- data/lib/rad/init.rb +3 -1
- data/lib/rad/rad_processor.rb +11 -0
- data/lib/rad/rad_rewriter.rb +1 -1
- data/lib/rad/tasks/build_and_make.rake +25 -12
- data/lib/rad/variable_processing.rb +116 -0
- data/lib/test/test_array_processing.rb +78 -0
- data/lib/test/test_variable_processing.rb +188 -0
- metadata +29 -3
@@ -0,0 +1,70 @@
|
|
1
|
+
class I2cEeprom < ArduinoPlugin
|
2
|
+
|
3
|
+
# RAD plugins are c methods, directives, external variables and assignments and calls
|
4
|
+
# that may be added to the main setup method
|
5
|
+
# function prototypes not needed since we generate them automatically
|
6
|
+
|
7
|
+
# directives, external variables and setup assignments and calls can be added rails style (not c style)
|
8
|
+
|
9
|
+
|
10
|
+
# add to directives
|
11
|
+
plugin_directives "#define BUF_SIZE 32"
|
12
|
+
|
13
|
+
|
14
|
+
# add to external variables
|
15
|
+
external_variables "byte i2cbuf[BUF_SIZE];"
|
16
|
+
|
17
|
+
# add the following to the setup method
|
18
|
+
# add_to_setup
|
19
|
+
|
20
|
+
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
|
21
|
+
int rdata = data;
|
22
|
+
Wire.beginTransmission(deviceaddress);
|
23
|
+
Wire.send((int)(eeaddress >> 8)); // Address High Byte
|
24
|
+
Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte
|
25
|
+
Wire.send(rdata);
|
26
|
+
Wire.endTransmission();
|
27
|
+
}
|
28
|
+
|
29
|
+
// Address is a page address, 6-bit (63). More and end will wrap around
|
30
|
+
// But data can be maximum of 28 bytes, because the Wire library has a buffer of 32 bytes
|
31
|
+
|
32
|
+
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
|
33
|
+
Wire.beginTransmission(deviceaddress);
|
34
|
+
Wire.send((int)(eeaddresspage >> 8)); // Address High Byte
|
35
|
+
Wire.send((int)(eeaddresspage & 0xFF)); // Address Low Byte
|
36
|
+
byte c;
|
37
|
+
for ( c = 0; c < length; c++)
|
38
|
+
Wire.send(data[c]);
|
39
|
+
Wire.endTransmission();
|
40
|
+
delay(10); // need some delay
|
41
|
+
}
|
42
|
+
|
43
|
+
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
|
44
|
+
byte rdata = 0xFF;
|
45
|
+
Wire.beginTransmission(deviceaddress);
|
46
|
+
Wire.send((int)(eeaddress >> 8)); // Address High Byte
|
47
|
+
Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte
|
48
|
+
Wire.endTransmission();
|
49
|
+
Wire.requestFrom(deviceaddress,1);
|
50
|
+
if (Wire.available()) rdata = Wire.receive();
|
51
|
+
return rdata;
|
52
|
+
}
|
53
|
+
|
54
|
+
// should not read more than 28 bytes at a time!
|
55
|
+
|
56
|
+
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
|
57
|
+
Wire.beginTransmission(deviceaddress);
|
58
|
+
Wire.send((int)(eeaddress >> 8)); // Address High Byte
|
59
|
+
Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte
|
60
|
+
Wire.endTransmission();
|
61
|
+
Wire.requestFrom(deviceaddress,length);
|
62
|
+
//int c = 0;
|
63
|
+
for ( int c = 0; c < length; c++ )
|
64
|
+
if (Wire.available()) buffer[c] = Wire.receive();
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
end
|
data/lib/rad/arduino_plugin.rb
CHANGED
@@ -54,6 +54,7 @@ def initialize #:nodoc:
|
|
54
54
|
# $plugin_methods_hash = $plugin_methods_hash || {} ### new
|
55
55
|
# $plugins_to_load = $plugins_to_load || [] ### new
|
56
56
|
$add_to_setup = $add_to_setup || []
|
57
|
+
$load_libraries = $load_libraries || []
|
57
58
|
|
58
59
|
|
59
60
|
end
|
@@ -65,6 +66,10 @@ end
|
|
65
66
|
# if the sketch has them, we include the plugins in the build...
|
66
67
|
# otherwise not..
|
67
68
|
|
69
|
+
def include_wire
|
70
|
+
$load_libraries << "Wire" unless $load_libraries.include?("Wire")
|
71
|
+
end
|
72
|
+
|
68
73
|
|
69
74
|
def add_to_setup(*args)
|
70
75
|
if args
|
@@ -96,6 +101,24 @@ end
|
|
96
101
|
end
|
97
102
|
end
|
98
103
|
|
104
|
+
def add_blink_m_struct
|
105
|
+
$plugin_structs[:blink_m] = <<-STR
|
106
|
+
typedef struct _blinkm_script_line {
|
107
|
+
uint8_t dur;
|
108
|
+
uint8_t cmd[4]; // cmd,arg1,arg2,arg3
|
109
|
+
} blinkm_script_line;
|
110
|
+
STR
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.add_blink_m_struct
|
114
|
+
$plugin_structs[:blink_m] = <<-STR
|
115
|
+
typedef struct _blinkm_script_line {
|
116
|
+
uint8_t dur;
|
117
|
+
uint8_t cmd[4]; // cmd,arg1,arg2,arg3
|
118
|
+
} blinkm_script_line;
|
119
|
+
STR
|
120
|
+
end
|
121
|
+
|
99
122
|
def add_debounce_struct
|
100
123
|
$plugin_structs[:debounce] = <<-STR
|
101
124
|
struct debounce {
|
@@ -160,7 +183,7 @@ end
|
|
160
183
|
## need a test for this
|
161
184
|
## fails on string interpolation, but since ruby_to_c also currently fails ...
|
162
185
|
sketch_string = sketch_string.gsub(/#(?!\{.*\}).*/, "")
|
163
|
-
plugin_signatures << plugin_string.scan(/^\s((
|
186
|
+
plugin_signatures << plugin_string.scan(/^\s*(((#{PLUGIN_C_VAR_TYPES})\s*)+\w*\(.*\))/)
|
164
187
|
# gather just the method name and then add to #plugin_methods_hash
|
165
188
|
plugin_signatures[0].map {|sig| "#{sig[0]}"}.each {|m| plugin_methods << m.gsub!(/^.*\s(\w*)\(.*\)/, '\1')}
|
166
189
|
# we don't know the methods yet, so...
|
@@ -182,13 +205,13 @@ end
|
|
182
205
|
first_process = plugin_string
|
183
206
|
# todo: need to add plugin names to the methods, so we can add them as comments in the c code
|
184
207
|
# gather the c methods
|
185
|
-
$plugin_methods << first_process.scan(/^\s*(((
|
186
|
-
plugin_signatures << first_process.scan(/^\s((
|
208
|
+
$plugin_methods << first_process.scan(/^\s*(((#{PLUGIN_C_VAR_TYPES}).*\)).*(\n.*)*^\s*\})/)
|
209
|
+
plugin_signatures << first_process.scan(/^\s((#{PLUGIN_C_VAR_TYPES}).*\(.*\))/)
|
187
210
|
$plugin_signatures << plugin_signatures[0].map {|sig| "#{sig[0]};"}
|
188
211
|
## strip out the methods and pass it back
|
189
212
|
result = plugin_string
|
190
213
|
# strip out the c methods so we have only ruby before eval
|
191
|
-
result.gsub(/^\s*(
|
214
|
+
result.gsub(/^\s*(#{PLUGIN_C_VAR_TYPES}).*(\n.*)*^\s*\}/, "" )
|
192
215
|
|
193
216
|
end
|
194
217
|
|
data/lib/rad/arduino_sketch.rb
CHANGED
@@ -153,23 +153,24 @@
|
|
153
153
|
#
|
154
154
|
|
155
155
|
class ArduinoSketch
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
@@frequency_inc = FALSE
|
156
|
+
|
157
|
+
include ExternalVariableProcessing
|
158
|
+
|
159
|
+
# find another way to do this
|
160
|
+
@@frequency_inc = FALSE
|
161
|
+
@@twowire_inc = FALSE
|
161
162
|
|
162
163
|
def initialize #:nodoc:
|
163
164
|
@servo_settings = [] # need modular way to add this
|
164
165
|
@debounce_settings = [] # need modular way to add this
|
165
166
|
@servo_pins = []
|
166
167
|
@debounce_pins = []
|
167
|
-
|
168
|
-
|
168
|
+
$external_array_vars = []
|
169
|
+
$external_vars =[]
|
169
170
|
$external_var_identifiers = []
|
170
171
|
$sketch_methods = []
|
171
|
-
$load_libraries
|
172
|
-
$
|
172
|
+
$load_libraries ||= []
|
173
|
+
$defines ||= []
|
173
174
|
|
174
175
|
@declarations = []
|
175
176
|
@pin_modes = {:output => [], :input => []}
|
@@ -249,19 +250,19 @@ class ArduinoSketch
|
|
249
250
|
if v.split(",")[0] == "char"
|
250
251
|
## default is 40 characters
|
251
252
|
if v.split(",")[2]
|
252
|
-
|
253
|
+
$external_vars << "#{v.split(",")[0]}* #{k}[#{v.split(",")[2].lstrip}];"
|
253
254
|
else
|
254
|
-
|
255
|
+
$external_vars << "#{v.split(",")[0]} #{k}[40] = \"#{v.split(",")[1].lstrip}\";"
|
255
256
|
end
|
256
257
|
else
|
257
|
-
|
258
|
+
$external_vars << "#{v.split(",")[0]} #{k} =#{v.split(",")[1]};"
|
258
259
|
end
|
259
260
|
else
|
260
261
|
if v.split(",")[0] == "char"
|
261
|
-
|
262
|
+
$external_vars << "#{v.split(",")[0]} #{k}[40];"
|
262
263
|
else
|
263
264
|
|
264
|
-
|
265
|
+
$external_vars << "#{v.split(",")[0]} #{k};"
|
265
266
|
end
|
266
267
|
end
|
267
268
|
# check chars work here
|
@@ -270,7 +271,7 @@ class ArduinoSketch
|
|
270
271
|
end
|
271
272
|
end
|
272
273
|
|
273
|
-
|
274
|
+
# phasing this out
|
274
275
|
def add_to_setup(*args)
|
275
276
|
if args
|
276
277
|
args.each do |arg|
|
@@ -279,17 +280,70 @@ class ArduinoSketch
|
|
279
280
|
end
|
280
281
|
end
|
281
282
|
|
282
|
-
#
|
283
|
+
# phasing this out
|
283
284
|
def external_arrays(*args)
|
284
285
|
if args
|
285
286
|
args.each do |arg|
|
286
|
-
|
287
|
+
$external_array_vars << arg
|
287
288
|
end
|
288
289
|
end
|
289
290
|
|
290
291
|
end
|
292
|
+
|
293
|
+
# array "char buffer[32]"
|
294
|
+
# result: char buffer[32];
|
295
|
+
# array "char buffer[32]"
|
296
|
+
# result: char buffer[32];
|
297
|
+
# todo
|
298
|
+
# need to feed array external array identifiers to rtc if they are in plugins or libraries
|
299
|
+
def array(arg)
|
300
|
+
if arg
|
301
|
+
arg = arg.chomp.rstrip.lstrip
|
302
|
+
name = arg.scan(/\s*(\w*)\[\d*\]?/).first.first
|
303
|
+
if /\w*\[\d*\]\s*\=\s*\{(.*)\}/ =~ arg
|
304
|
+
assignment = arg.scan(/\w*\[\d*\]\s*\=\s*\{(.*)\}/).first.first
|
305
|
+
array_size = assignment.split(",").length
|
306
|
+
if /\[(\s*)\]/ =~ arg
|
307
|
+
arg.gsub!(/(\[\d*\])/, "[#{array_size}]")
|
308
|
+
end
|
309
|
+
end
|
310
|
+
arg = arg.scan(/^((\s*|\w*)*\s*\w*\[\d*\])?/).first.first
|
311
|
+
arg = "#{arg};" unless arg[-1,1] == ";"
|
312
|
+
$external_var_identifiers << name unless $external_var_identifiers.include?(name)
|
313
|
+
# add array_name declaration
|
314
|
+
$external_array_vars << arg unless $external_array_vars.include?(arg)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# define "DS1307_SEC 0"
|
319
|
+
# result: #define DS1307_SEC 0
|
320
|
+
def define(arg)
|
321
|
+
if arg
|
322
|
+
arg = arg.chomp.rstrip.lstrip
|
323
|
+
arg = "#define #{arg}"
|
324
|
+
$defines << arg
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
# need better location.. module?
|
329
|
+
def self.add_to_setup(meth)
|
330
|
+
meth = meth.gsub("setup", "additional_setup")
|
331
|
+
post_process_ruby_to_c_methods(meth)
|
332
|
+
end
|
333
|
+
|
334
|
+
def self.post_process_ruby_to_c_methods(e)
|
335
|
+
clean_c_methods = []
|
336
|
+
# need to take a look at the \(unsigned in the line below not sure if we are really trying to catch something like that
|
337
|
+
if e !~ /^\s*(#{C_VAR_TYPES})(\W{1,6}|\(unsigned\()(#{$external_var_identifiers.join("|")})/ || $external_var_identifiers.empty?
|
338
|
+
# use the list of identifers the external_vars method of the sketch and remove the parens the ruby2c sometime adds to variables
|
339
|
+
# keep an eye on the gsub!.. are we getting nil errors
|
340
|
+
e.gsub!(/((#{$external_var_identifiers.join("|")})\(\))/, '\2') unless $external_var_identifiers.empty?
|
341
|
+
clean_c_methods << e
|
342
|
+
end
|
343
|
+
return clean_c_methods.join( "\n" )
|
344
|
+
end
|
291
345
|
|
292
|
-
#
|
346
|
+
# Configure a single pin for output and setup a method to refer to that pin, i.e.:
|
293
347
|
#
|
294
348
|
# output_pin 7, :as => :led
|
295
349
|
#
|
@@ -322,11 +376,28 @@ class ArduinoSketch
|
|
322
376
|
return
|
323
377
|
when :freq_out || :freq_gen || :frequency_generator
|
324
378
|
frequency_timer(num, opts)
|
325
|
-
|
379
|
+
return
|
380
|
+
when :i2c
|
381
|
+
two_wire(num, opts) unless @@twowire_inc
|
382
|
+
return #
|
383
|
+
when :i2c_eeprom
|
384
|
+
two_wire(num, opts) unless @@twowire_inc
|
385
|
+
return #
|
386
|
+
when :i2c_ds1307
|
387
|
+
two_wire(num, opts) unless @@twowire_inc
|
388
|
+
ds1307(num, opts)
|
389
|
+
return #
|
390
|
+
when :i2c_blinkm
|
391
|
+
two_wire(num, opts) unless @@twowire_inc
|
392
|
+
blinkm
|
393
|
+
return #
|
394
|
+
when :onewire
|
395
|
+
one_wire(num, opts)
|
396
|
+
return #
|
326
397
|
else
|
327
|
-
|
398
|
+
raise ArgumentError, "today's device choices are: :servo, :original_servo_setup, :pa_lcd, :sf_lcd, :freq_out,:i2c, :i2c_eeprom, :i2c_ds1307, and :i2c_blinkm got #{opts[:device]}"
|
399
|
+
end
|
328
400
|
end
|
329
|
-
end
|
330
401
|
|
331
402
|
# remove the next 14 lines as soon as documentation on new :device => :servo option is out
|
332
403
|
|
@@ -454,7 +525,7 @@ class ArduinoSketch
|
|
454
525
|
# transitioning to :device => :button syntax
|
455
526
|
if opts[:latch] || opts[:device] == :button
|
456
527
|
if opts[:device] == :button
|
457
|
-
opts[:latch] ||= :
|
528
|
+
opts[:latch] ||= :off
|
458
529
|
end
|
459
530
|
# add debounce settings to dbce struct array
|
460
531
|
ArduinoPlugin.add_debounce_struct
|
@@ -499,7 +570,7 @@ class ArduinoSketch
|
|
499
570
|
end
|
500
571
|
|
501
572
|
# Treat a pair of digital I/O pins as a serial line. See: http://www.arduino.cc/en/Tutorial/SoftwareSerial
|
502
|
-
|
573
|
+
def software_serial(rx, tx, opts={})
|
503
574
|
raise ArgumentError, "can only define rx from Fixnum, got #{rx.class}" unless rx.is_a?(Fixnum)
|
504
575
|
raise ArgumentError, "can only define tx from Fixnum, got #{tx.class}" unless tx.is_a?(Fixnum)
|
505
576
|
|
@@ -512,6 +583,7 @@ class ArduinoSketch
|
|
512
583
|
accessor << "SoftwareSerial& #{opts[ :as ]}() {"
|
513
584
|
accessor << "\treturn _#{opts[ :as ]};"
|
514
585
|
accessor << "}"
|
586
|
+
@@swser_inc ||= FALSE
|
515
587
|
if (@@swser_inc == FALSE) # on second instance this stuff can't be repeated
|
516
588
|
@@swser_inc = TRUE
|
517
589
|
accessor << "int read(SoftwareSerial& s) {"
|
@@ -552,6 +624,7 @@ class ArduinoSketch
|
|
552
624
|
accessor << "SWSerLCDpa& #{opts[ :as ]}() {"
|
553
625
|
accessor << "\treturn _#{opts[ :as ]};"
|
554
626
|
accessor << "}"
|
627
|
+
@@slcdpa_inc ||= FALSE
|
555
628
|
if (@@slcdpa_inc == FALSE) # on second instance this stuff can't be repeated - BBR
|
556
629
|
@@slcdpa_inc = TRUE
|
557
630
|
accessor << "void print( SWSerLCDpa& s, uint8_t b ) {"
|
@@ -634,7 +707,7 @@ class ArduinoSketch
|
|
634
707
|
|
635
708
|
@signatures << "SWSerLCDpa& #{opts[ :as ]}();"
|
636
709
|
|
637
|
-
@other_setup << "
|
710
|
+
@other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
|
638
711
|
end
|
639
712
|
end
|
640
713
|
|
@@ -654,6 +727,7 @@ class ArduinoSketch
|
|
654
727
|
accessor << "SWSerLCDsf& #{opts[ :as ]}() {"
|
655
728
|
accessor << "\treturn _#{opts[ :as ]};"
|
656
729
|
accessor << "}"
|
730
|
+
@@slcdsf_inc ||= FALSE # assign only if nil
|
657
731
|
if (@@slcdsf_inc == FALSE) # on second instance this stuff can't be repeated - BBR
|
658
732
|
@@slcdsf_inc = TRUE
|
659
733
|
accessor << "void print( SWSerLCDsf& s, uint8_t b ) {"
|
@@ -706,16 +780,14 @@ class ArduinoSketch
|
|
706
780
|
|
707
781
|
@signatures << "SWSerLCDsf& #{opts[ :as ]}();"
|
708
782
|
|
709
|
-
@other_setup << "
|
783
|
+
@other_setup << "\t_#{opts[ :as ]}.begin(#{rate});"
|
710
784
|
end
|
711
785
|
end
|
712
786
|
|
713
787
|
|
714
788
|
|
715
|
-
|
716
|
-
|
717
|
-
def servo(spin, opts={}) # servo motor routines # how about pin instead of spin
|
718
|
-
raise ArgumentError, "can only define spin from Fixnum, got #{spin.class}" unless spin.is_a?(Fixnum)
|
789
|
+
def servo(pin, opts={}) # servo motor routines #
|
790
|
+
raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
|
719
791
|
|
720
792
|
minp = opts[:min] ? opts[:min] : 544
|
721
793
|
maxp = opts[:max] ? opts[:max] : 2400
|
@@ -727,7 +799,7 @@ class ArduinoSketch
|
|
727
799
|
accessor << "Servo& #{opts[ :as ]}() {"
|
728
800
|
accessor << "\treturn _#{opts[ :as ]};"
|
729
801
|
accessor << "}"
|
730
|
-
|
802
|
+
@@servo_inc ||= FALSE
|
731
803
|
if (@@servo_inc == FALSE) # on second instance this stuff can't be repeated - BBR
|
732
804
|
@@servo_inc = TRUE
|
733
805
|
accessor << "void detach( Servo& s ) {"
|
@@ -754,16 +826,17 @@ class ArduinoSketch
|
|
754
826
|
|
755
827
|
@signatures << "Servo& #{opts[ :as ]}();"
|
756
828
|
|
757
|
-
@other_setup << "\t_#{opts[ :as ]}.attach(#{
|
758
|
-
@other_setup << "\t_#{opts[ :as ]}.attach(#{
|
829
|
+
@other_setup << "\t_#{opts[ :as ]}.attach(#{pin}, #{opts[:position]}, #{minp}, #{maxp});" if opts[:position]
|
830
|
+
@other_setup << "\t_#{opts[ :as ]}.attach(#{pin}, #{minp}, #{maxp});" unless opts[:position]
|
759
831
|
|
760
832
|
end
|
761
833
|
end
|
762
834
|
|
763
|
-
|
764
|
-
|
835
|
+
def frequency_timer(pin, opts={}) # frequency timer routines
|
836
|
+
|
765
837
|
raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
|
766
838
|
raise ArgumentError, "only pin 11 may be used for freq_out, got #{pin}" unless pin == 11
|
839
|
+
|
767
840
|
if opts[:enable]
|
768
841
|
raise ArgumentError, "enable option must include the frequency or period option" unless opts[:frequency] || opts[:period]
|
769
842
|
end
|
@@ -777,28 +850,29 @@ class ArduinoSketch
|
|
777
850
|
|
778
851
|
if opts[:as]
|
779
852
|
|
853
|
+
@@frequency_inc = TRUE
|
780
854
|
@declarations << "FrequencyTimer2 _#{opts[ :as ]} = FrequencyTimer2();"
|
781
855
|
accessor = []
|
782
856
|
$load_libraries << "FrequencyTimer2"
|
783
857
|
accessor << "FrequencyTimer2& #{opts[ :as ]}() {"
|
784
858
|
accessor << "\treturn _#{opts[ :as ]};"
|
785
859
|
accessor << "}"
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
860
|
+
# add ||=
|
861
|
+
# if (@@frequency_inc == FALSE) # on second instance this stuff can't be repeated - BBR
|
862
|
+
# @@frequency_inc = TRUE
|
863
|
+
accessor << "void set_frequency( FrequencyTimer2& s, int b ) {"
|
864
|
+
accessor << "\treturn s.setPeriod( 1000000L/b );"
|
865
|
+
accessor << "}"
|
866
|
+
accessor << "void set_period( FrequencyTimer2& s, int b ) {"
|
867
|
+
accessor << "\treturn s.setPeriod( b );"
|
868
|
+
accessor << "}"
|
869
|
+
accessor << "void enable( FrequencyTimer2& s ) {"
|
870
|
+
accessor << "\treturn s.enable();"
|
871
|
+
accessor << "}"
|
872
|
+
accessor << "void disable( FrequencyTimer2& s ) {"
|
873
|
+
accessor << "\treturn s.disable();"
|
874
|
+
accessor << "}"
|
875
|
+
# end
|
802
876
|
|
803
877
|
@accessors << accessor.join( "\n" )
|
804
878
|
|
@@ -810,119 +884,284 @@ class ArduinoSketch
|
|
810
884
|
@other_setup << "\tFrequencyTimer2::enable();" if opts[:enable] == :true
|
811
885
|
end
|
812
886
|
end
|
813
|
-
|
814
887
|
|
815
|
-
|
816
|
-
|
888
|
+
def one_wire(pin, opts={})
|
889
|
+
raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
|
890
|
+
|
891
|
+
if opts[:as]
|
892
|
+
@declarations << "OneWire _#{opts[ :as ]} = OneWire(#{pin});"
|
893
|
+
accessor = []
|
894
|
+
$load_libraries << "OneWire"
|
895
|
+
accessor << "OneWire& #{opts[ :as ]}() {"
|
896
|
+
accessor << "\treturn _#{opts[ :as ]};"
|
897
|
+
accessor << "}"
|
898
|
+
@@onewire_inc ||= FALSE
|
899
|
+
if (@@onewire_inc == FALSE) # on second instance this stuff can't be repeated - BBR
|
900
|
+
@@onewire_inc = TRUE
|
901
|
+
accessor << "uint8_t reset(OneWire& s) {"
|
902
|
+
accessor << "\treturn s.reset();"
|
903
|
+
accessor << "}"
|
904
|
+
accessor << "void skip(OneWire& s) {"
|
905
|
+
accessor << "\treturn s.skip();"
|
906
|
+
accessor << "}"
|
907
|
+
accessor << "void write(OneWire& s, uint8_t v, uint8_t p = 0) {" # "power = 0" ?????
|
908
|
+
accessor << "\treturn s.write( v, p );"
|
909
|
+
accessor << "}"
|
910
|
+
accessor << "uint8_t read(OneWire& s) {"
|
911
|
+
accessor << "\treturn s.read();"
|
912
|
+
accessor << "}"
|
913
|
+
accessor << "void write_bit( OneWire& s, uint8_t b ) {"
|
914
|
+
accessor << "\treturn s.write_bit( b );"
|
915
|
+
accessor << "}"
|
916
|
+
accessor << "uint8_t read_bit(OneWire& s) {"
|
917
|
+
accessor << "\treturn s.read_bit();"
|
918
|
+
accessor << "}"
|
919
|
+
accessor << "void depower(OneWire& s) {"
|
920
|
+
accessor << "\treturn s.depower();"
|
921
|
+
accessor << "}"
|
922
|
+
end
|
923
|
+
@accessors << accessor.join( "\n" )
|
924
|
+
|
925
|
+
@signatures << "OneWire& #{opts[ :as ]}();"
|
926
|
+
end
|
927
|
+
end
|
928
|
+
|
929
|
+
def two_wire (pin, opts={}) # i2c Two-Wire
|
930
|
+
|
931
|
+
raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
|
932
|
+
raise ArgumentError, "only pin 19 may be used for i2c, got #{pin}" unless pin == 19
|
933
|
+
|
934
|
+
if opts[:as]
|
935
|
+
|
936
|
+
@@twowire_inc = TRUE
|
937
|
+
@declarations << "TwoWire _wire = TwoWire();"
|
938
|
+
# @declarations << "TwoWire _#{opts[ :as ]} = TwoWire();"
|
939
|
+
accessor = []
|
940
|
+
$load_libraries << "Wire"
|
941
|
+
accessor << "TwoWire& wire() {"
|
942
|
+
accessor << "\treturn _wire;"
|
943
|
+
# accessor << "TwoWire& #{opts[ :as ]}() {"
|
944
|
+
# accessor << "\treturn _#{opts[ :as ]};"
|
945
|
+
accessor << "}"
|
946
|
+
accessor << "void begin( TwoWire& s) {"
|
947
|
+
accessor << "\treturn s.begin();"
|
948
|
+
accessor << "}"
|
949
|
+
accessor << "void begin( TwoWire& s, uint8_t a) {"
|
950
|
+
accessor << "\treturn s.begin(a);"
|
951
|
+
accessor << "}"
|
952
|
+
accessor << "void begin( TwoWire& s, int a) {"
|
953
|
+
accessor << "\treturn s.begin(a);"
|
954
|
+
accessor << "}"
|
955
|
+
accessor << "void beginTransmission( TwoWire& s, uint8_t a ) {"
|
956
|
+
accessor << "\treturn s.beginTransmission( a );"
|
957
|
+
accessor << "}"
|
958
|
+
accessor << "void beginTransmission( TwoWire& s, int a ) {"
|
959
|
+
accessor << "\treturn s.beginTransmission( a );"
|
960
|
+
accessor << "}"
|
961
|
+
accessor << "void endTransmission( TwoWire& s ) {"
|
962
|
+
accessor << "\treturn s.endTransmission();"
|
963
|
+
accessor << "}"
|
964
|
+
accessor << "void requestFrom( TwoWire& s, uint8_t a, uint8_t q) {"
|
965
|
+
accessor << "\treturn s.requestFrom( a, q );"
|
966
|
+
accessor << "}"
|
967
|
+
accessor << "void requestFrom( TwoWire& s, int a, int q) {"
|
968
|
+
accessor << "\treturn s.requestFrom( a, q );"
|
969
|
+
accessor << "}"
|
970
|
+
accessor << "void send( TwoWire& s, uint8_t d) {"
|
971
|
+
accessor << "\treturn s.send(d);"
|
972
|
+
accessor << "}"
|
973
|
+
accessor << "void send( TwoWire& s, int d) {"
|
974
|
+
accessor << "\treturn s.send(d);"
|
975
|
+
accessor << "}"
|
976
|
+
accessor << "void send( TwoWire& s, char* d) {"
|
977
|
+
accessor << "\treturn s.send(d);"
|
978
|
+
accessor << "}"
|
979
|
+
accessor << "void send( TwoWire& s, uint8_t* d, uint8_t q) {"
|
980
|
+
accessor << "\treturn s.send( d, q );"
|
981
|
+
accessor << "}"
|
982
|
+
accessor << "uint8_t available( TwoWire& s) {"
|
983
|
+
accessor << "\treturn s.available();"
|
984
|
+
accessor << "}"
|
985
|
+
accessor << "uint8_t receive( TwoWire& s) {"
|
986
|
+
accessor << "\treturn s.receive();"
|
987
|
+
accessor << "}"
|
988
|
+
|
989
|
+
@accessors << accessor.join( "\n" )
|
990
|
+
|
991
|
+
@signatures << "TwoWire& wire();"
|
992
|
+
# @signatures << "TwoWire& #{opts[ :as ]}();"
|
993
|
+
|
994
|
+
@other_setup << "\t_wire.begin();" if opts[:enable] == :true
|
995
|
+
# @other_setup << "\t_#{opts[ :as ]}.begin();" if opts[:enable] == :true
|
996
|
+
|
997
|
+
end
|
998
|
+
end
|
999
|
+
|
1000
|
+
def ds1307(pin, opts={}) # DS1307 motor routines
|
1001
|
+
raise ArgumentError, "can only define pin from Fixnum, got #{pin.class}" unless pin.is_a?(Fixnum)
|
1002
|
+
raise ArgumentError, "only pin 19 may be used for i2c, got #{pin}" unless pin == 19
|
1003
|
+
# raise ArgumentError, "only one DS1307 may be used for i2c" if @@ds1307_inc == :true
|
1004
|
+
|
1005
|
+
if opts[:as]
|
1006
|
+
@@ds1307_inc = TRUE
|
1007
|
+
@declarations << "DS1307 _#{opts[ :as ]} = DS1307();"
|
1008
|
+
accessor = []
|
1009
|
+
$load_libraries << "DS1307"
|
1010
|
+
accessor << "DS1307& #{opts[ :as ]}() {"
|
1011
|
+
accessor << "\treturn _#{opts[ :as ]};"
|
1012
|
+
accessor << "}"
|
1013
|
+
accessor << "int get( DS1307& s, int b, boolean r ) {"
|
1014
|
+
accessor << "\treturn s.get( b, r );"
|
1015
|
+
accessor << "}"
|
1016
|
+
accessor << "void set( DS1307& s, int b, int r ) {"
|
1017
|
+
accessor << "\treturn s.set( b, r );"
|
1018
|
+
accessor << "}"
|
1019
|
+
accessor << "void start( DS1307& s ) {"
|
1020
|
+
accessor << "\treturn s.start();"
|
1021
|
+
accessor << "}"
|
1022
|
+
accessor << "void stop( DS1307& s ) {"
|
1023
|
+
accessor << "\treturn s.stop();"
|
1024
|
+
accessor << "}"
|
1025
|
+
|
1026
|
+
@accessors << accessor.join( "\n" )
|
1027
|
+
|
1028
|
+
@signatures << "DS1307& #{opts[ :as ]}();"
|
1029
|
+
@other_setup << "\t_#{opts[ :as ]}.start();" if opts[:rtcstart]
|
1030
|
+
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
|
1035
|
+
|
1036
|
+
def blinkm
|
1037
|
+
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
|
1041
|
+
|
1042
|
+
|
817
1043
|
def compose_setup #:nodoc: also composes headers and signatures
|
1044
|
+
|
1045
|
+
declarations = []
|
1046
|
+
plugin_directives = []
|
1047
|
+
signatures = []
|
1048
|
+
external_vars = []
|
1049
|
+
setup = []
|
1050
|
+
additional_setup =[]
|
1051
|
+
helpers = []
|
1052
|
+
main = []
|
818
1053
|
result = []
|
819
1054
|
|
820
|
-
|
1055
|
+
declarations << comment_box( "Auto-generated by RAD" )
|
821
1056
|
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
$
|
1057
|
+
declarations << "#include <WProgram.h>\n"
|
1058
|
+
declarations << "#include <SoftwareSerial.h>\n"
|
1059
|
+
$load_libraries.each { |lib| declarations << "#include <#{lib}.h>" } unless $load_libraries.nil?
|
1060
|
+
$defines.each { |d| declarations << d }
|
826
1061
|
|
827
|
-
|
828
|
-
$plugin_directives.each {|dir|
|
1062
|
+
plugin_directives << comment_box( 'plugin directives' )
|
1063
|
+
$plugin_directives.each {|dir| plugin_directives << dir } unless $plugin_directives.nil? || $plugin_directives.empty?
|
829
1064
|
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
@signatures.each {|sig|
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
$plugin_external_variables.each { |meth| result << meth } unless $plugin_external_variables.nil? || $plugin_external_variables.empty?
|
1065
|
+
signatures << comment_box( 'method signatures' )
|
1066
|
+
signatures << "void loop();"
|
1067
|
+
signatures << "void setup();"
|
1068
|
+
signatures << "// sketch signatures"
|
1069
|
+
@signatures.each {|sig| signatures << sig}
|
1070
|
+
signatures << "// plugin signatures"
|
1071
|
+
$plugin_signatures.each {|sig| signatures << sig } unless $plugin_signatures.nil? || $plugin_signatures.empty?
|
1072
|
+
external_vars << "\n" + comment_box( "plugin external variables" )
|
1073
|
+
$plugin_external_variables.each { |meth| external_vars << meth } unless $plugin_external_variables.nil? || $plugin_external_variables.empty?
|
840
1074
|
|
841
|
-
|
842
|
-
$plugin_structs.each { |k,v|
|
1075
|
+
signatures << "\n" + comment_box( "plugin structs" )
|
1076
|
+
$plugin_structs.each { |k,v| signatures << v } unless $plugin_structs.nil? || $plugin_structs.empty?
|
843
1077
|
|
844
|
-
|
1078
|
+
external_vars << "\n" + comment_box( "sketch external variables" )
|
845
1079
|
|
846
|
-
|
847
|
-
|
848
|
-
|
1080
|
+
$external_vars.each {|v| external_vars << v }
|
1081
|
+
external_vars << ""
|
1082
|
+
external_vars << "// servo_settings array"
|
849
1083
|
|
850
1084
|
array_size = @servo_settings.empty? ? 1 : @servo_pins.max + 1 # conserve space if no variables needed
|
851
|
-
|
852
|
-
|
1085
|
+
external_vars << "struct servo serv[#{array_size}] = { #{@servo_settings.join(", ")} };" if $plugin_structs[:servo]
|
1086
|
+
external_vars << ""
|
853
1087
|
|
854
|
-
|
1088
|
+
external_vars << "// debounce array"
|
855
1089
|
array_size = @debounce_settings.empty? ? 1 : @debounce_pins.max + 1 # conserve space if no variables needed
|
856
|
-
|
857
|
-
|
1090
|
+
external_vars << "struct debounce dbce[#{array_size}] = { #{@debounce_settings.join(", ")} };" if $plugin_structs[:debounce]
|
1091
|
+
external_vars << ""
|
858
1092
|
|
859
|
-
|
1093
|
+
$external_array_vars.each { |var| external_vars << var } if $external_array_vars
|
860
1094
|
|
861
|
-
|
862
|
-
@declarations.each {|dec|
|
863
|
-
|
864
|
-
@accessors.each {|ac|
|
1095
|
+
external_vars << "\n" + comment_box( "variable and accessors" )
|
1096
|
+
@declarations.each {|dec| external_vars << dec}
|
1097
|
+
external_vars << ""
|
1098
|
+
@accessors.each {|ac| external_vars << ac}
|
865
1099
|
|
866
|
-
|
1100
|
+
# fix naming
|
1101
|
+
external_vars << "\n" + comment_box( "assembler declarations" )
|
867
1102
|
unless @assembler_declarations.empty?
|
868
|
-
|
1103
|
+
external_vars << <<-CODE
|
869
1104
|
extern "C" {
|
870
1105
|
#{@assembler_declarations.join("\n")}
|
871
1106
|
}
|
872
1107
|
CODE
|
873
1108
|
end
|
874
1109
|
|
875
|
-
|
876
|
-
|
877
|
-
|
1110
|
+
external_vars << "\n" + comment_box( "setup" )
|
1111
|
+
setup << "void setup() {"
|
1112
|
+
setup << "\t// pin modes"
|
878
1113
|
|
879
1114
|
@pin_modes.each do |k,v|
|
880
1115
|
v.each do |value|
|
881
|
-
|
1116
|
+
setup << "\tpinMode(#{value}, #{k.to_s.upcase});"
|
882
1117
|
end
|
883
1118
|
end
|
884
1119
|
|
885
1120
|
@pullups.each do |pin|
|
886
|
-
|
1121
|
+
setup << "\tdigitalWrite( #{pin}, HIGH ); // enable pull-up resistor for input"
|
887
1122
|
end
|
888
1123
|
|
889
1124
|
unless $add_to_setup.nil? || $add_to_setup.empty?
|
890
|
-
|
891
|
-
$add_to_setup.each {|item|
|
1125
|
+
setup << "\t// setup from plugins via add_to_setup method"
|
1126
|
+
$add_to_setup.each {|item| setup << "\t#{item}"}
|
892
1127
|
end
|
893
1128
|
|
894
1129
|
unless @other_setup.empty?
|
895
|
-
|
896
|
-
|
1130
|
+
setup << "\t// other setup"
|
1131
|
+
setup << @other_setup.join( "\n" )
|
897
1132
|
end
|
898
1133
|
|
899
|
-
|
1134
|
+
additional_setup << "}\n"
|
900
1135
|
|
901
|
-
|
902
|
-
|
903
|
-
|
1136
|
+
helpers << comment_box( "helper methods" )
|
1137
|
+
helpers << "\n// RAD built-in helpers"
|
1138
|
+
helpers << @helper_methods.lstrip
|
904
1139
|
|
905
|
-
|
1140
|
+
helpers << "\n" + comment_box( "plugin methods" )
|
906
1141
|
# need to add plugin name to this...
|
907
|
-
$plugin_methods.each { |meth|
|
1142
|
+
$plugin_methods.each { |meth| helpers << "#{meth[0][0]}\n" } unless $plugin_methods.nil? || $plugin_methods.empty?
|
908
1143
|
|
909
|
-
|
910
|
-
|
1144
|
+
helpers << "\n// serial helpers"
|
1145
|
+
helpers << serial_boilerplate.lstrip
|
911
1146
|
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
1147
|
+
main << "\n" + comment_box( "main() function" )
|
1148
|
+
main << "int main() {"
|
1149
|
+
main << "\tinit();"
|
1150
|
+
main << "\tsetup();"
|
1151
|
+
main << "\tfor( ;; ) { loop(); }"
|
1152
|
+
main << "\treturn 0;"
|
1153
|
+
main << "}"
|
1154
|
+
|
1155
|
+
main << "\n" + comment_box( "loop! Autogenerated by RubyToC, sorry it's ugly." )
|
919
1156
|
|
920
|
-
|
1157
|
+
return [declarations, plugin_directives, signatures, external_vars, setup, additional_setup, helpers, main]
|
921
1158
|
|
922
|
-
return result.join( "\n" )
|
923
1159
|
end
|
924
1160
|
|
925
1161
|
|
1162
|
+
|
1163
|
+
|
1164
|
+
|
926
1165
|
# Write inline assembler code. 'Name' is a symbol representing the name of the function to be defined in the assembly code; 'signature' is the function signature for the function being defined; and 'code' is the assembly code itself (both of these last two arguments are strings). See an example here: http://rad.rubyforge.org/examples/assembler_test.html
|
927
1166
|
def assembler(name, signature, code)
|
928
1167
|
@assembler_declarations << signature
|
@@ -943,7 +1182,7 @@ class ArduinoSketch
|
|
943
1182
|
def self.pre_process(sketch_string) #:nodoc:
|
944
1183
|
result = sketch_string
|
945
1184
|
# add external vars to each method (needed for better translation, will be removed in make:upload)
|
946
|
-
result.gsub!(/(^\s*def\s.\w*(\(.*\))?)/, '\1' + " \n #{
|
1185
|
+
result.gsub!(/(^\s*def\s.\w*(\(.*\))?)/, '\1' + " \n #{$external_vars.join(" \n ")}" )
|
947
1186
|
# gather method names
|
948
1187
|
sketch_methods = result.scan(/^\s*def\s.\w*/)
|
949
1188
|
sketch_methods.each {|m| $sketch_methods << m.gsub(/\s*def\s*/, "") }
|