madrona-rad 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/History.txt +75 -0
  2. data/License.txt +282 -0
  3. data/Manifest.txt +47 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +139 -0
  6. data/bin/rad +197 -0
  7. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +267 -0
  8. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +64 -0
  9. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +254 -0
  10. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +57 -0
  11. data/lib/libraries/Servo/Servo.cpp +152 -0
  12. data/lib/libraries/Servo/Servo.h +33 -0
  13. data/lib/libraries/Servo/keywords.txt +25 -0
  14. data/lib/plugins/debounce.rb +116 -0
  15. data/lib/plugins/debug_output_to_lcd.rb +71 -0
  16. data/lib/plugins/input_output_state.rb +84 -0
  17. data/lib/plugins/mem_test.rb +37 -0
  18. data/lib/plugins/servo_pulse.rb +31 -0
  19. data/lib/plugins/servo_setup.rb +86 -0
  20. data/lib/plugins/smoother.rb +54 -0
  21. data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
  22. data/lib/rad/arduino_plugin.rb +202 -0
  23. data/lib/rad/arduino_sketch.rb +952 -0
  24. data/lib/rad/generators/makefile/makefile.erb +243 -0
  25. data/lib/rad/generators/makefile/makefile.rb +39 -0
  26. data/lib/rad/init.rb +12 -0
  27. data/lib/rad/rad_processor.rb +66 -0
  28. data/lib/rad/rad_rewriter.rb +94 -0
  29. data/lib/rad/tasks/build_and_make.rake +159 -0
  30. data/lib/rad/tasks/rad.rb +2 -0
  31. data/lib/rad/todo.txt +13 -0
  32. data/lib/rad/version.rb +9 -0
  33. data/lib/rad.rb +5 -0
  34. data/scripts/txt2html +67 -0
  35. data/setup.rb +1585 -0
  36. data/spec/models/arduino_sketch_spec.rb +82 -0
  37. data/spec/models/spec_helper.rb +2 -0
  38. data/spec/spec.opts +1 -0
  39. data/website/examples/assembler_test.rb.html +73 -0
  40. data/website/examples/gps_reader.rb.html +39 -0
  41. data/website/examples/hello_world.rb.html +38 -0
  42. data/website/examples/serial_motor.rb.html +41 -0
  43. data/website/index.html +177 -0
  44. data/website/index.txt +64 -0
  45. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  46. data/website/stylesheets/screen.css +169 -0
  47. data/website/template.rhtml +48 -0
  48. metadata +120 -0
@@ -0,0 +1,243 @@
1
+ # Arduino makefile
2
+ #
3
+ # This makefile allows you to build sketches from the command line
4
+ # without the Arduino environment (or Java).
5
+ #
6
+ # The Arduino environment does preliminary processing on a sketch before
7
+ # compiling it. If you're using this makefile instead, you'll need to do
8
+ # a few things differently:
9
+ #
10
+ # - Give your program's file a .cpp extension (e.g. foo.cpp).
11
+ #
12
+ # - Put this line at top of your code: #include <WProgram.h>
13
+ #
14
+ # - Write prototypes for all your functions (or define them before you
15
+ # call them). A prototype declares the types of parameters a
16
+ # function will take and what type of value it will return. This
17
+ # means that you can have a call to a function before the definition
18
+ # of the function. A function prototype looks like the first line of
19
+ # the function, with a semi-colon at the end. For example:
20
+ # int digitalRead(int pin);
21
+ #
22
+ # - Write a main() function for your program that returns an int, calls
23
+ # init() and setup() once (in that order), and then calls loop()
24
+ # repeatedly():
25
+ #
26
+ # int main()
27
+ # {
28
+ # init();
29
+ # setup();
30
+ #
31
+ # for (;;)
32
+ # loop();
33
+ #
34
+ # return 0;
35
+ # }
36
+ #
37
+ # Instructions for using the makefile:
38
+ #
39
+ # 1. Copy this file into the folder with your sketch.
40
+ #
41
+ # 2. Below, modify the line containing "TARGET" to refer to the name of
42
+ # of your program's file without an extension (e.g. TARGET = foo).
43
+ #
44
+ # 3. Modify the line containg "ARDUINO" to point the directory that
45
+ # contains the Arduino core (for normal Arduino installations, this
46
+ # is the hardware/cores/arduino sub-directory).
47
+ #
48
+ # 4. Modify the line containing "PORT" to refer to the filename
49
+ # representing the USB or serial connection to your Arduino board
50
+ # (e.g. PORT = /dev/tty.USB0). If the exact name of this file
51
+ # changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
52
+ #
53
+ # 5. At the command line, change to the directory containing your
54
+ # program's file and the makefile.
55
+ #
56
+ # 6. Type "make" and press enter to compile/verify your program.
57
+ #
58
+ # 7. Type "make upload", reset your Arduino board, and press enter to
59
+ # upload your program to the Arduino board.
60
+ #
61
+ # $Id$
62
+
63
+ PORT = <%= params['serial_port'] %>
64
+ TARGET = <%= params['target'] %>
65
+ ARDUINO = <%= params['arduino_root'] %>/hardware/cores/arduino
66
+ SOFTWARE_SERIAL = <%= params['arduino_root'] %>/hardware/libraries/SoftwareSerial
67
+ LIBRARY_ROOT = <%= params['libraries_root'] %>
68
+ SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
69
+ $(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
70
+ $(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
71
+ $(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
72
+ CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(SOFTWARE_SERIAL)/SoftwareSerial.cpp<%= params['libraries'].collect{|l| " $(LIBRARY_ROOT)/#{ l }/#{l }.cpp"}.join('') %>
73
+ MCU = <%= params['mcu'] %>
74
+ <% if params['asm_files'] %>ASRC = <%= params['asm_files'].join(' ') %><% end %>
75
+ F_CPU = 16000000
76
+ FORMAT = ihex
77
+ UPLOAD_RATE = 19200
78
+ BIN_DIR = <%= params['arduino_root'] %>/hardware/tools/avr/bin
79
+
80
+ # Name of this Makefile (used for "make depend").
81
+ MAKEFILE = Makefile
82
+
83
+ # Debugging format.
84
+ # Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
85
+ # AVR (extended) COFF requires stabs, plus an avr-objcopy run.
86
+ DEBUG = stabs
87
+
88
+ OPT = s
89
+
90
+ # Place -D or -U options here
91
+ CDEFS = -DF_CPU=$(F_CPU)
92
+ CXXDEFS = -DF_CPU=$(F_CPU)
93
+
94
+ # Place -I options here
95
+ CINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)<% params['libraries'].each do |l| %> -I$(LIBRARY_ROOT)/<%= l %><% end %>
96
+ +CXXINCS = -I$(ARDUINO) -I$(SOFTWARE_SERIAL)<% params['libraries'].each do |l| %> -I$(LIBRARY_ROOT)/<%= l %><% end %>
97
+
98
+ # Compiler flag to set the C Standard level.
99
+ # c89 - "ANSI" C
100
+ # gnu89 - c89 plus GCC extensions
101
+ # c99 - ISO C99 standard (not yet fully implemented)
102
+ # gnu99 - c99 plus GCC extensions
103
+ CSTANDARD = -std=gnu99
104
+ CDEBUG = -g$(DEBUG)
105
+ CWARN = -Wall -Wstrict-prototypes
106
+ CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
107
+ #CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
108
+
109
+ CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
110
+ CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
111
+ #ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
112
+ LDFLAGS = -lm
113
+
114
+
115
+ # Programming support using avrdude. Settings and variables.
116
+ AVRDUDE_PROGRAMMER = stk500
117
+ AVRDUDE_PORT = $(PORT)
118
+ AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
119
+ AVRDUDE_FLAGS = -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
120
+ -b $(UPLOAD_RATE) -C <%= params['arduino_root'] %>/hardware/tools/avr/etc/avrdude.conf
121
+
122
+ # Program settings
123
+ CC = $(BIN_DIR)/avr-gcc
124
+ CXX = $(BIN_DIR)/avr-g++
125
+ OBJCOPY = $(BIN_DIR)/avr-objcopy
126
+ OBJDUMP = $(BIN_DIR)/avr-objdump
127
+ AR = $(BIN_DIR)/avr-ar
128
+ SIZE = $(BIN_DIR)/avr-size
129
+ NM = $(BIN_DIR)/avr-nm
130
+ AVRDUDE = $(BIN_DIR)/avrdude
131
+ REMOVE = rm -f
132
+ MV = mv -f
133
+
134
+ # Define all object files.
135
+ OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
136
+
137
+ # Define all listing files.
138
+ LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
139
+
140
+ # Combine all necessary flags and optional flags.
141
+ # Add target processor to flags.
142
+ ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
143
+ ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
144
+ ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
145
+
146
+
147
+ # Default target.
148
+ all: build
149
+
150
+ build: elf hex
151
+
152
+ elf: $(TARGET).elf
153
+ hex: $(TARGET).hex
154
+ eep: $(TARGET).eep
155
+ lss: $(TARGET).lss
156
+ sym: $(TARGET).sym
157
+
158
+ # Program the device.
159
+ upload: $(TARGET).hex
160
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
161
+
162
+
163
+
164
+
165
+ # Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
166
+ COFFCONVERT=$(OBJCOPY) --debugging \
167
+ --change-section-address .data-0x800000 \
168
+ --change-section-address .bss-0x800000 \
169
+ --change-section-address .noinit-0x800000 \
170
+ --change-section-address .eeprom-0x810000
171
+
172
+
173
+ coff: $(TARGET).elf
174
+ $(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof
175
+
176
+
177
+ extcoff: $(TARGET).elf
178
+ $(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof
179
+
180
+
181
+ .SUFFIXES: .elf .hex .eep .lss .sym
182
+
183
+ .elf.hex:
184
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
185
+
186
+ .elf.eep:
187
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
188
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
189
+
190
+ # Create extended listing file from ELF output file.
191
+ .elf.lss:
192
+ $(OBJDUMP) -h -S $< > $@
193
+
194
+ # Create a symbol table from ELF output file.
195
+ .elf.sym:
196
+ $(NM) -n $< > $@
197
+
198
+
199
+ core.a: $(OBJ)
200
+ @for i in $(OBJ); do echo $(AR) rcs core.a $$i; $(AR) rcs core.a $$i; done
201
+
202
+ # Link: create ELF output file from library.
203
+ $(TARGET).elf: core.a
204
+ $(CC) $(ALL_CFLAGS) -o $@ $(TARGET).cpp -L. core.a $(LDFLAGS)
205
+
206
+ # Compile: create object files from C++ source files.
207
+ .cpp.o:
208
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
209
+
210
+ # Compile: create object files from C source files.
211
+ .c.o:
212
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
213
+
214
+
215
+ # Compile: create assembler files from C source files.
216
+ .c.s:
217
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
218
+
219
+
220
+ # Assemble: create object files from assembler source files.
221
+ .S.o:
222
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
223
+
224
+
225
+
226
+ # Target: clean project.
227
+ clean:
228
+ $(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \
229
+ $(TARGET).map $(TARGET).sym $(TARGET).lss core.a \
230
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
231
+
232
+ depend:
233
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
234
+ then \
235
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
236
+ $(MAKEFILE).$$$$ && \
237
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
238
+ fi
239
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
240
+ >> $(MAKEFILE); \
241
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)
242
+
243
+ .PHONY: all build elf hex eep lss sym program coff extcoff clean depend
@@ -0,0 +1,39 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+
4
+ class Makefile
5
+ class << self
6
+
7
+ # build the sketch Makefile for the given template based on the values in its software and hardware config files
8
+ def compose_for_sketch(sketch_name)
9
+ params = hardware_params.merge software_params
10
+ params['target'] = sketch_name
11
+
12
+ params['libraries_root'] = "#{File.expand_path(RAD_ROOT)}/vendor/libraries"
13
+ params['libraries'] = libraries
14
+
15
+ params['asm_files'] = Dir.entries( File.expand_path(RAD_ROOT) + "/" + PROJECT_DIR_NAME ).select{|e| e =~ /\.S/}
16
+
17
+ e = ERB.new File.read("#{File.dirname(__FILE__)}/makefile.erb")
18
+
19
+ File.open("#{RAD_ROOT}/#{sketch_name}/Makefile", "w") do |f|
20
+ f << e.result(binding)
21
+ end
22
+ end
23
+
24
+ def libraries
25
+ Dir.entries("#{RAD_ROOT}/vendor/libraries").select{|e| !(e =~ /\./)}
26
+ end
27
+
28
+ def hardware_params
29
+ return @hardware_params if @hardware_params
30
+ return @hardware_params = YAML.load_file( "#{RAD_ROOT}/config/hardware.yml")
31
+ end
32
+
33
+ def software_params
34
+ return @software_params if @software_params
35
+ return @software_params = YAML.load_file( "#{RAD_ROOT}/config/software.yml" )
36
+ end
37
+
38
+ end
39
+ end
data/lib/rad/init.rb ADDED
@@ -0,0 +1,12 @@
1
+ RAD_ROOT = "#{File.dirname(__FILE__)}/../.." unless defined?(RAD_ROOT)
2
+
3
+ unless defined?(PROJECT_DIR_NAME)
4
+ a = File.expand_path(File.expand_path("#{RAD_ROOT}")).split("/")
5
+ PROJECT_DIR_NAME = a[a.length-1]
6
+ end
7
+
8
+
9
+ %w(generators/makefile/makefile.rb rad_processor.rb rad_rewriter.rb arduino_sketch.rb arduino_plugin.rb tasks/rad.rb).each do |path|
10
+ require File.expand_path("#{RAD_ROOT}/vendor/rad/#{path}")
11
+ end
12
+
@@ -0,0 +1,66 @@
1
+ require 'ruby_to_ansi_c'
2
+
3
+ class RADProcessor < RubyToAnsiC
4
+
5
+ def self.translator
6
+ unless defined? @translator then
7
+ @translator = CompositeSexpProcessor.new
8
+ @translator << RADRewriter.new
9
+ @translator << TypeChecker.new
10
+ @translator << R2CRewriter.new
11
+ @translator << self.new
12
+ @translator.on_error_in(:defn) do |processor, exp, err|
13
+ result = processor.expected.new
14
+ case result
15
+ when Array then
16
+ result << :error
17
+ end
18
+ msg = "// ERROR: #{err.class}: #{err}"
19
+ msg += " in #{exp.inspect}" unless exp.nil? or $TESTING
20
+ msg += " from #{caller.join(', ')}" unless $TESTING
21
+ result << msg
22
+ result
23
+ end
24
+ end
25
+ @translator
26
+ end
27
+
28
+ def process_lasgn(exp)
29
+ out = ""
30
+
31
+ var = exp.shift
32
+ value = exp.shift
33
+ # grab the size of the args, if any, before process converts to a string
34
+ arg_count = 0
35
+ arg_count = value.length - 1 if value.first == :array
36
+ args = value
37
+
38
+ exp_type = exp.sexp_type
39
+ @env.add var.to_sym, exp_type
40
+ var_type = self.class.c_type exp_type
41
+
42
+ if exp_type.list? then
43
+ assert_type args, :array
44
+
45
+ raise "array must be of one type" unless args.sexp_type == Type.homo
46
+
47
+ # HACK: until we figure out properly what to do w/ zarray
48
+ # before we know what its type is, we will default to long.
49
+ array_type = args.sexp_types.empty? ? 'void *' : self.class.c_type(args.sexp_types.first)
50
+ # we can fix array here..
51
+ args.shift # :arglist
52
+ out << "#{var} = (#{array_type}) malloc(sizeof(#{array_type}) * #{args.length});\n"
53
+ args.each_with_index do |o,i|
54
+ out << "#{var}[#{i}] = #{process o};\n"
55
+ end
56
+ else
57
+ out << "#{var} = #{process args}"
58
+ end
59
+
60
+ out.sub!(/;\n\Z/, '')
61
+
62
+ return out
63
+ end
64
+
65
+
66
+ end
@@ -0,0 +1,94 @@
1
+ require 'ruby_to_ansi_c'
2
+
3
+ class RADRewriter < Rewriter
4
+
5
+ def process_iter(exp)
6
+ call = process exp.shift
7
+ var = process exp.shift
8
+ body = process exp.shift
9
+
10
+ var = s(:dasgn_curr, Unique.next) if var.nil?
11
+
12
+ assert_type call, :call
13
+
14
+ if call[2] != :each then # TODO: fix call[n] (api)
15
+ call.shift # :call
16
+ lhs = call.shift
17
+ method_name = call.shift
18
+
19
+ case method_name
20
+ when :downto then
21
+ var.shift #
22
+ start_value = lhs
23
+ finish_value = call.pop.pop # not sure about this
24
+ var_name = var.shift
25
+ body.find_and_replace_all(:dvar, :lvar)
26
+ result = s(:dummy,
27
+ s(:lasgn, var_name, start_value),
28
+ s(:while,
29
+ s(:call, s(:lvar, var_name), :>=,
30
+ s(:arglist, finish_value)),
31
+ s(:block,
32
+ body,
33
+ s(:lasgn, var_name,
34
+ s(:call, s(:lvar, var_name), :-,
35
+ s(:arglist, s(:lit, 1))))), true))
36
+ when :upto then
37
+ # REFACTOR: completely duped from above and direction changed
38
+ var.shift #
39
+ start_value = lhs
40
+ finish_value = call.pop.pop # not sure about this
41
+ var_name = var.shift
42
+ body.find_and_replace_all(:dvar, :lvar)
43
+ result = s(:dummy,
44
+ s(:lasgn, var_name, start_value),
45
+ s(:while,
46
+ s(:call, s(:lvar, var_name), :<=,
47
+ s(:arglist, finish_value)),
48
+ s(:block,
49
+ body,
50
+ s(:lasgn, var_name,
51
+ s(:call, s(:lvar, var_name), :+,
52
+ s(:arglist, s(:lit, 1))))), true))
53
+ when :times then
54
+ # REFACTOR: mostly duped from above and gave default start value of 0
55
+ # and a finish value that was the start value above
56
+ var.shift
57
+ start_value = s(:lit, 0)
58
+ finish_value = lhs
59
+ var_name = var.shift
60
+ body.find_and_replace_all(:dvar, :lvar)
61
+ result = s(:dummy,
62
+ s(:lasgn, var_name, start_value),
63
+ s(:while,
64
+ s(:call, s(:lvar, var_name), :<=,
65
+ s(:arglist, finish_value)),
66
+ s(:block,
67
+ body,
68
+ s(:lasgn, var_name,
69
+ s(:call, s(:lvar, var_name), :+,
70
+ s(:arglist, s(:lit, 1))))), true))
71
+ when :define_method then
72
+ # BEFORE: [:iter, [:call, nil, :define_method, [:array, [:lit, :bmethod_added]]], [:dasgn_curr, :x], [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]
73
+ # we want to get it rewritten for the scope/block context, so:
74
+ # - throw call away
75
+ # - rewrite to args
76
+ # - plop body into a scope
77
+ # AFTER: [:block, [:args, :x], [:call, [:lvar, :x], :+, [:arglist, [:lit, 1]]]]
78
+ var.find_and_replace_all(:dasgn_curr, :args)
79
+ body.find_and_replace_all(:dvar, :lvar)
80
+ result = s(:block, var, body)
81
+ else
82
+ # HACK we butchered call up top
83
+ result = s(:iter, s(:call, lhs, method_name, call.shift), var, body)
84
+ end
85
+ else
86
+ if var.nil? then
87
+ var = s(:lvar, Unique.next)
88
+ end
89
+
90
+ s(:iter, call, var, body)
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,159 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../init.rb")
2
+ require 'ruby_to_ansi_c'
3
+
4
+ C_VAR_TYPES = "unsigned|int|long|double|str|char"
5
+
6
+ namespace :make do
7
+
8
+ desc "compile the sketch and then upload it to your Arduino board"
9
+ task :upload => :compile do
10
+ if Makefile.hardware_params['physical_reset']
11
+ puts "Reset the Arduino and hit enter.\n==If your board doesn't need it, you can turn off this prompt in config/software.yml=="
12
+ STDIN.gets.chomp
13
+ end
14
+ sh %{cd #{RAD_ROOT}/#{@sketch_name}; make upload}
15
+ end
16
+
17
+ desc "generate a makefile and use it to compile the .cpp"
18
+ task :compile => [:clean_sketch_dir, "build:sketch"] do # should also depend on "build:sketch"
19
+ Makefile.compose_for_sketch( @sketch_name )
20
+ # not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}
21
+ sh %{cd #{RAD_ROOT}/#{@sketch_name}; make depend; make}
22
+ end
23
+
24
+ desc "generate a makefile and use it to compile the .cpp using the current .cpp file"
25
+ task :compile_cpp => ["build:sketch_dir", :clean_sketch_dir] do # should also depend on "build:sketch"
26
+ Makefile.compose_for_sketch( @sketch_name )
27
+ # not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}
28
+ sh %{cd #{RAD_ROOT}/#{@sketch_name}; make depend; make}
29
+ end
30
+
31
+ desc "generate a makefile and use it to compile the .cpp and upload it using current .cpp file"
32
+ task :upload_cpp => ["build:sketch_dir", :clean_sketch_dir] do # should also depend on "build:sketch"
33
+ Makefile.compose_for_sketch( @sketch_name )
34
+ # not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}
35
+ sh %{cd #{RAD_ROOT}/#{@sketch_name}; make depend; make upload}
36
+ end
37
+
38
+ task :clean_sketch_dir => ["build:file_list", "build:sketch_dir"] do
39
+ @sketch_name = @sketch_class.split(".").first
40
+ FileList.new(Dir.entries("#{RAD_ROOT}/#{@sketch_name}")).exclude("#{@sketch_name}.cpp").exclude(/^\./).each do |f|
41
+ sh %{rm #{RAD_ROOT}/#{@sketch_name}/#{f}}
42
+ end
43
+ end
44
+ end
45
+
46
+ namespace :build do
47
+
48
+ desc "actually build the sketch"
49
+ task :sketch => [:file_list, :sketch_dir, :gather_required_plugins, :plugin_setup, :setup] do
50
+ klass = @sketch_class.split(".").first.split("_").collect{|c| c.capitalize}.join("")
51
+ eval ArduinoSketch.pre_process(File.read(@sketch_class))
52
+ c_methods = []
53
+ sketch_signatures = []
54
+ $sketch_methods.each {|m| c_methods << RADProcessor.translate(constantize(klass), m) }
55
+ c_methods.each {|meth| sketch_signatures << "#{meth.scan(/^\w*\s?\*?\n.*\)/)[0].gsub("\n", " ")};" }
56
+ clean_c_methods = []
57
+ c_methods.join("\n").each_with_index do |e,i|
58
+ # need to take a look at the \(unsigned in the line below not sure if we are really trying to catch something like that
59
+ if e !~ /^\s*(#{C_VAR_TYPES})(\W{1,6}|\(unsigned\()(#{$external_var_identifiers.join("|")})/ || $external_var_identifiers.empty?
60
+ # use the list of identifers the external_vars method of the sketch and remove the parens the ruby2c sometime adds to variables
61
+ e.gsub(/((#{$external_var_identifiers.join("|")})\(\))/, '\2') unless $external_var_identifiers.empty?
62
+ clean_c_methods << e
63
+ end
64
+ end
65
+ c_methods_with_timer = clean_c_methods.join.gsub(/loop\(\)\s\{/,"loop() {\ntrack_total_loop_time();")
66
+ @setup.gsub!("// sketch signatures", "// sketch signatures\n#{ sketch_signatures.join("\n")}") unless sketch_signatures.empty?
67
+ result = "#{@setup}\n#{c_methods_with_timer}\n"
68
+ name = @sketch_class.split(".").first
69
+ File.open("#{name}/#{name}.cpp", "w"){|f| f << result}
70
+ end
71
+
72
+ # needs to write the library include and the method signatures
73
+ desc "build setup function"
74
+ task :setup do
75
+ klass = @sketch_class.split(".").first.split("_").collect{|c| c.capitalize}.join("")
76
+ eval "class #{klass} < ArduinoSketch; end;"
77
+
78
+ @@as = ArduinoSketch.new
79
+
80
+ delegate_methods = @@as.methods - Object.new.methods
81
+ delegate_methods.reject!{|m| m == "compose_setup"}
82
+
83
+ delegate_methods.each do |meth|
84
+ constantize(klass).module_eval <<-CODE
85
+ def self.#{meth}(*args)
86
+ @@as.#{meth}(*args)
87
+ end
88
+ CODE
89
+ end
90
+ eval File.read(@sketch_class)
91
+ @setup = @@as.compose_setup
92
+ end
93
+
94
+ desc "add plugin methods"
95
+ task :plugin_setup do
96
+ $plugins_to_load.each do |name|
97
+ klass = name.split(".").first.split("_").collect{|c| c.capitalize}.join("")
98
+ eval "class #{klass} < ArduinoPlugin; end;"
99
+
100
+ @@ps = ArduinoPlugin.new
101
+ plugin_delegate_methods = @@ps.methods - Object.new.methods
102
+ plugin_delegate_methods.reject!{|m| m == "compose_setup"}
103
+
104
+ plugin_delegate_methods.each do |meth|
105
+ constantize(klass).module_eval <<-CODE
106
+ def self.#{meth}(*args)
107
+ @@ps.#{meth}(*args)
108
+ end
109
+ CODE
110
+ end
111
+
112
+ eval ArduinoPlugin.process(File.read("vendor/plugins/#{name}"))
113
+
114
+ end
115
+ @@no_plugins = ArduinoPlugin.new if @plugin_names.empty?
116
+ end
117
+
118
+ desc "determine which plugins to load based on use of methods in sketch"
119
+ task :gather_required_plugins do
120
+ @plugin_names.each do |name|
121
+ ArduinoPlugin.check_for_plugin_use(File.read(@sketch_class), File.read("vendor/plugins/#{name}"), name )
122
+ end
123
+ puts "#{$plugins_to_load.length} of #{$plugin_methods_hash.length} plugins are being loaded: #{$plugins_to_load.join(", ")}"
124
+ end
125
+
126
+ desc "setup target directory named after your sketch class"
127
+ task :sketch_dir => [:file_list] do
128
+ mkdir_p "#{@sketch_class.split(".").first}"
129
+ end
130
+
131
+ task :file_list do
132
+ # take another look at this, since if the root directory name is changed, everything breaks
133
+ # perhaps we generate a constant when the project is generated an pop it here or in the init file
134
+ @sketch_directory = File.expand_path("#{File.dirname(__FILE__)}/../../../").split("/").last
135
+ # multiple sketches are possible with rake make:upload sketch=new_sketch
136
+ @sketch_class = ENV['sketch'] ? "#{ENV['sketch']}.rb" : "#{@sketch_directory}.rb"
137
+ @file_names = []
138
+ @plugin_names = []
139
+ Dir.entries( File.expand_path(RAD_ROOT) ).each do |f|
140
+ if (f =~ /\.rb$/)
141
+ @file_names << f
142
+ end
143
+ end
144
+ Dir.entries( File.expand_path("#{RAD_ROOT}/vendor/plugins/") ).each do |f|
145
+ if (f =~ /\.rb$/)
146
+ @plugin_names << f
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ #yoinked from Rails
153
+ def constantize(camel_cased_word)
154
+ unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
155
+ raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
156
+ end
157
+
158
+ Object.module_eval("::#{$1}", __FILE__, __LINE__)
159
+ end
@@ -0,0 +1,2 @@
1
+ require 'rake'
2
+ Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext }
data/lib/rad/todo.txt ADDED
@@ -0,0 +1,13 @@
1
+ TODO:
2
+ =====
3
+
4
+ Future:
5
+ - complete library system: script/install library some_library
6
+ - bin/rad:
7
+ - setup and use a ~/.rad for new project defaults
8
+ - put repository on git
9
+ - project gallery (examples with movies)
10
+ - testing framework
11
+ - implement wire lib
12
+ - subclasses of ArduinoSketch (should just work, but what are they for?)
13
+ - simulator
@@ -0,0 +1,9 @@
1
+ module Rad #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 2
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
data/lib/rad.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Rad
2
+ end
3
+
4
+ require 'rad/version'
5
+ require 'rad/init'