Class: DenkoCLI::Generator
- Inherits:
-
Object
- Object
- DenkoCLI::Generator
- Includes:
- Helper
- Defined in:
- lib/denko_cli/targets.rb,
lib/denko_cli/packages.rb,
lib/denko_cli/generator.rb
Constant Summary collapse
- STANDARD_PACKAGES =
PACKAGES.each_key.map do |package| package unless PACKAGES[package][:only] end.compact
- TARGETS =
{ # Core is core. core: [:core], # Specific features for the old mega168 chips. mega168: [:core, :one_wire, :tone, :i2c, :spi, :servo], # Other ATmega chips do everything. # Add bit bang serial for 328p / UNO since it has no extra hardware UART. mega: STANDARD_PACKAGES + [:uart_bb], # No tone, infrared or EEPROM on SAM3X / Due. sam3x: STANDARD_PACKAGES - [:tone, :ir_out, :eeprom], # No EEPROM on SAMD / Zero. samd: STANDARD_PACKAGES - [:eeprom], # No IR out and WS2812 on the UNO R4. WS2812 compiles but doesn't work. ra4m1: STANDARD_PACKAGES - [:ir_out, :led_array], # ESP8266 + ESP32 use a different IR library. esp8266: STANDARD_PACKAGES - [:ir_out] + [:ir_out_esp], esp32: STANDARD_PACKAGES - [:ir_out] + [:ir_out_esp], # RP2040 can't use WS2812 yet. rp2040: STANDARD_PACKAGES - [:led_array], }
- PACKAGES =
File locations are defined relative to the src/lib directory.
{ # The core package is always included. core: { description: "Core Denko Library", directive: nil, files: [ "Denko.h", "DenkoDefines.h", "Denko.cpp", "DenkoCoreIO.cpp", "DenkoPulseInput.cpp", "../../vendor/board-maps/BoardMap.h", ] }, eeprom: { description: "Built-in EEPROM support", directive: "DENKO_EEPROM", files: [ "DenkoEEPROM.cpp", ] }, one_wire: { description: "OneWire bus support", directive: "DENKO_ONE_WIRE", files: [ "DenkoOneWire.cpp", ] }, spi_bb: { description: "Bit Bang SPI support", directive: "DENKO_SPI_BB", files: [ "DenkoSPI.cpp", "DenkoSPIBB.cpp", ] }, spi: { description: "SPI support", directive: "DENKO_SPI", files: [ "DenkoSPI.cpp", ] }, i2c: { description: "I2C device support", directive: "DENKO_I2C", files: [ "DenkoI2C.cpp", ] }, uart_bb: { description: "Bit bang serial output", directive: "DENKO_UART_BB", only: [:mega, :mega168], files: [ "DenkoUARTBB.cpp", ] }, uart: { description: "Hardware UART I/O", directive: "DENKO_UART", files: [ "DenkoUART.cpp", ] }, servo: { description: "Servo support", directive: "DENKO_SERVO", files: [ "DenkoServo.cpp", ] }, tone: { description: "Tone support", directive: "DENKO_TONE", files: [ "DenkoTone.cpp", ] }, ir_out: { description: "Transmit infrared signals", directive: "DENKO_IR_OUT", exclude: [:esp8266, :esp32], files: [ "DenkoIROut.cpp", ] }, ir_out_esp: { description: "Transmit infrared signals with the ESP8266 and ESP32", directive: "DENKO_IR_OUT", only: [:esp8266, :esp32], files: [ "DenkoIROutESP.cpp", ] }, led_array: { description: "Support for various protocols that control (RGB) LED arrays.", directive: "DENKO_LED_ARRAY", files: [ "DenkoLEDArray.cpp", ] } }
Instance Attribute Summary collapse
-
#options ⇒ Object
Returns the value of attribute options.
Class Method Summary collapse
Instance Method Summary collapse
- #append_target ⇒ Object
- #define(directive) ⇒ Object
-
#gsub_defines(from, to) ⇒ Object
Run gsub! on contents of src/lib/Denko.h specifically.
-
#initialize(options = {}) ⇒ Generator
constructor
A new instance of Generator.
- #make_output_dir ⇒ Object
- #output_dir ⇒ Object
- #read ⇒ Object
- #sketch_filename ⇒ Object
- #target_config ⇒ Object
- #user_config ⇒ Object
- #write ⇒ Object
Methods included from Helper
#error, #missing_files, #targets, #usage
Constructor Details
#initialize(options = {}) ⇒ Generator
Returns a new instance of Generator.
12 13 14 15 |
# File 'lib/denko_cli/generator.rb', line 12 def initialize(={}) @options = append_target end |
Instance Attribute Details
#options ⇒ Object
Returns the value of attribute options.
10 11 12 |
# File 'lib/denko_cli/generator.rb', line 10 def @options end |
Class Method Details
.run!(options = {}) ⇒ Object
25 26 27 28 29 30 31 32 |
# File 'lib/denko_cli/generator.rb', line 25 def self.run!(={}) instance = self.new() instance.read instance.target_config instance.user_config instance.write end |
Instance Method Details
#append_target ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/denko_cli/generator.rb', line 17 def append_target [:target] = :mega unless [:target] # Preserve the source sketch name, since we need to copy that file. [:src_sketch_name] = [:sketch_name].dup [:sketch_name] << "_#{[:target]}" unless [:target] == :mega [:sketch_name] << "_#{::Denko::VERSION}" end |
#define(directive) ⇒ Object
108 109 110 |
# File 'lib/denko_cli/generator.rb', line 108 def define(directive) gsub_defines /\/\/.*#{directive}\s*$/, "#define #{directive}" end |
#gsub_defines(from, to) ⇒ Object
Run gsub! on contents of src/lib/Denko.h specifically.
113 114 115 116 117 118 119 |
# File 'lib/denko_cli/generator.rb', line 113 def gsub_defines(from, to) @packages[:core][:files].each do |f| if f[:path].match /DenkoDefines.h/ f[:contents].gsub!(from, to) end end end |
#make_output_dir ⇒ Object
156 157 158 159 160 |
# File 'lib/denko_cli/generator.rb', line 156 def make_output_dir dir = File.join [:working_dir], [:sketch_name] Dir::mkdir(dir) unless File.directory?(dir) dir end |
#output_dir ⇒ Object
152 153 154 |
# File 'lib/denko_cli/generator.rb', line 152 def output_dir [:output_dir] ||= make_output_dir end |
#read ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/denko_cli/generator.rb', line 34 def read @packages = PACKAGES files_missing = false # Replace each filepath with a hash containing the filepath and contents. @packages.each_key do |k| @packages[k][:files].map! do |f| contents = File.read(File.join([:src_dir], "lib", f)) # # Not using this anymroe. User has to install their own Arduino libraries. # # If the file is in src/vendor, it gets wrapped in an #ifdef # corresponding to the package directive. The entire package can now # be toggled in DenkoDefines.h. Without this, IDE would try to compile anyway. # if f.match /\Avendor/ # directive = @packages[k][:directive] # contents = "#include \"DenkoDefines.h\"\n#ifdef #{directive}\n" << contents << "\n#endif\n" # end { path: f, contents: contents } rescue files_missing = true puts "File missing: #{f}" end end # Show the text file when vendor files are missing if files_missing missing_files end # Read in the sketch itself. @sketch = File.read File.join([:src_dir], "#{[:src_sketch_name]}.ino") end |
#sketch_filename ⇒ Object
168 169 170 |
# File 'lib/denko_cli/generator.rb', line 168 def sketch_filename "#{[:sketch_name]}.ino" end |
#target_config ⇒ Object
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/denko_cli/generator.rb', line 97 def target_config target_packages = TARGETS[[:target]] target_packages.each do |t| directive = PACKAGES[t][:directive] define(directive) if directive end # Define the DENKO VERSION gsub_defines("#define DENKO_VERSION __VERSION__", "#define DENKO_VERSION \"#{::Denko::VERSION}\""); end |
#user_config ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/denko_cli/generator.rb', line 68 def user_config if [:baud] && serial? @sketch.gsub! "115200", [:baud] end if [:mac] && ethernet? octets = @options[:mac].split(':') bytes = octets.map { |o| "0x#{o.upcase}" } @sketch.gsub! "{ 0xDE, 0xAD, 0xBE, 0x30, 0x31, 0x32 }", bytes.inspect.gsub("[", "{").gsub("]", "}").gsub("\"", "") end if [:ip] && ethernet? @sketch.gsub! "192,168,0,77", [:ip].gsub(".", ",") end if [:ssid] && wifi? @sketch.gsub! "yourNetwork", [:ssid] end if [:password] && wifi? @sketch.gsub! "yourPassword", [:password] end if [:port] @sketch.gsub! "int port = 3466", "int port = #{[:port]}" end if [:debug] define("debug") end unless serial? define("TXRX_SPI") end end |
#write ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/denko_cli/generator.rb', line 121 def write # Write the sketch itself first. sketch = File.join(output_dir, sketch_filename) File.open(sketch, 'w') { |f| f.write @sketch } # Go through the @packages hash and copy source files. # Exclude only for target hardware incompatibility. # Eg. ESP8266 IR library is different and incompatible with AVR version. @packages.each_key do |k| # Check if the package should be included for this target. package = @packages[k] targeted = !package[:only] || package[:only].include?([:target]) excluded = package[:exclude] && package[:exclude].include?([:target]) # Append source file basename to the output dir to get output file path. # Then write the file contents to the destination path. if (targeted && !excluded) package[:files].each do |file| next unless file dest_path = File.join(output_dir, file[:path].split('/')[-1]) File.open(dest_path, 'w') { |f| f.write file[:contents] } end end end # Return the location of the sketch file. [:sketch_file] = sketch [:sketch_folder] = output_dir end |