diff options
Diffstat (limited to 'ruby')
-rw-r--r-- | ruby/dump.rb | 3 | ||||
-rw-r--r-- | ruby/hex-to-bin.rb | 9 | ||||
-rw-r--r-- | ruby/micronucleus.rb | 171 | ||||
-rw-r--r-- | ruby/upload.rb | 33 |
4 files changed, 0 insertions, 216 deletions
diff --git a/ruby/dump.rb b/ruby/dump.rb deleted file mode 100644 index 471d6d4..0000000 --- a/ruby/dump.rb +++ /dev/null @@ -1,3 +0,0 @@ -`rm temp-dump.bin` -`avrdude -c usbtiny -p t85 -U flash:r:temp-dump.bin:r` -puts open('temp-dump.bin').read(30).bytes.to_a.map { |x| x.to_s(16) }.join(' ') diff --git a/ruby/hex-to-bin.rb b/ruby/hex-to-bin.rb deleted file mode 100644 index 528a50f..0000000 --- a/ruby/hex-to-bin.rb +++ /dev/null @@ -1,9 +0,0 @@ -require_relative "../ruby/micronucleus.rb" - -# just converts a hex file to a binary file -program = HexProgram.new open ARGV.first - -File.open ARGV.first.split('/').last.sub(/\.hex$/, '') + '.raw', 'w' do |file| - file.write program.binary - file.close -end diff --git a/ruby/micronucleus.rb b/ruby/micronucleus.rb deleted file mode 100644 index 4b63af2..0000000 --- a/ruby/micronucleus.rb +++ /dev/null @@ -1,171 +0,0 @@ -require 'libusb' - -# Abstracts access to micronucleus avr tiny85 bootloader - can be used only to erase and upload bytes -class Micronucleus - Functions = [ - :get_info, - :write_page, - :erase_application, - :run_program - ] - - # return all micronucleus devices connected to computer - def self.all - usb = LIBUSB::Context.new - usb.devices.select { |device| - device.idVendor == 0x16d0 && device.idProduct == 0x0753 - }.map { |device| - self.new(device) - } - end - - def initialize devref - @device = devref - end - - def info - unless @info - result = control_transfer(function: :get_info, dataIn: 4) - flash_length, page_size, write_sleep = result.unpack('S>CC') - - @info = { - flash_length: flash_length, - page_size: page_size, - pages: (flash_length.to_f / page_size).ceil, - write_sleep: write_sleep.to_f / 1000.0, - version: "#{@device.bcdDevice >> 8}.#{@device.bcdDevice & 0xFF}", - version_numeric: @device.bcdDevice - } - end - - @info - end - - def erase! - puts "erasing" - info = self.info - control_transfer(function: :erase_application) - info[:pages].times do - sleep(info[:write_sleep]) # sleep for as many pages as the chip has to erase - end - puts "erased chip" - end - - # upload a new program - def program= bytestring - info = self.info - raise "Program too long!" if bytestring.bytesize > info[:flash_length] - bytes = bytestring.bytes.to_a - bytes.push(0xFF) while bytes.length < info[:flash_length] - - erase! - - address = 0 - bytes.each_slice(info[:page_size]) do |slice| - slice.push(0xFF) while slice.length < info[:page_size] # ensure every slice is one page_size long - pad out if needed - - puts "uploading @ #{address} of #{bytes.length}" - control_transfer(function: :write_page, wIndex: address, wValue: slice.length, dataOut: slice.pack('C*')) - sleep(info[:write_sleep]) - address += slice.length - end - end - - def finished - info = self.info - - puts "asking device to finish writing" - control_transfer(function: :run_program) - puts "waiting for device to finish" - - # sleep for as many pages as the chip could potentially need to write - this could be smarter - info[:pages].times do - sleep(info[:write_sleep]) - end - - @io.close - @io = nil - end - - def inspect - "<MicroBoot #{info[:version]}: #{(info[:flash_length] / 1024.0).round(1)} kb programmable>" - end - - protected - # raw opened device - def io - unless @io - @io = @device.open - end - - @io - end - - def control_transfer(opts = {}) - opts[:bRequest] = Functions.index(opts.delete(:function)) if opts[:function] - io.control_transfer({ - wIndex: 0, - wValue: 0, - bmRequestType: usb_request_type(opts), - timeout: 5000 - }.merge opts) - end - - # calculate usb request type - def usb_request_type opts #:nodoc: - value = LIBUSB::REQUEST_TYPE_VENDOR | LIBUSB::RECIPIENT_DEVICE - value |= LIBUSB::ENDPOINT_OUT if opts.has_key? :dataOut - value |= LIBUSB::ENDPOINT_IN if opts.has_key? :dataIn - return value - end -end - -class HexProgram - def initialize input - @bytes = Hash.new(0xFF) - input = input.read if input.is_a? IO - parse input - end - - def binary - bytes.pack('C*') - end - - def bytes - highest_address = @bytes.keys.max - - bytes = Array.new(highest_address + 1) { |index| - @bytes[index] - } - end - - protected - - def parse input_text - input_text.each_line do |line| - next unless line.start_with? ':' - line.chomp! - length = line[1..2].to_i(16) # usually 16 or 32 - address = line[3..6].to_i(16) # 16-bit start address - record_type = line[7..8].to_i(16) - data = line[9... 9 + (length * 2)] - checksum = line[9 + (length * 2).. 10 + (length * 2)].to_i(16) - checksum_section = line[1...9 + (length * 2)] - - checksum_calculated = checksum_section.chars.to_a.each_slice(2).map { |slice| - slice.join('').to_i(16) - }.reduce(0, &:+) - - checksum_calculated = (((checksum_calculated % 256) ^ 0xFF) + 1) % 256 - - raise "Hex file checksum mismatch @ #{line} should be #{checksum_calculated.to_s(16)}" unless checksum == checksum_calculated - - if record_type == 0 # data record - data_bytes = data.chars.each_slice(2).map { |slice| slice.join('').to_i(16) } - data_bytes.each_with_index do |byte, index| - @bytes[address + index] = byte - end - end - end - end -end
\ No newline at end of file diff --git a/ruby/upload.rb b/ruby/upload.rb deleted file mode 100644 index 32aefa9..0000000 --- a/ruby/upload.rb +++ /dev/null @@ -1,33 +0,0 @@ -require_relative './micronucleus' - -if ARGV[0] - if ARGV[0].end_with? '.hex' - puts "parsing input file as intel hex" - test_data = HexProgram.new(open ARGV[0]).binary - else - puts "parsing input file as raw binary" - test_data = open(ARGV[0]).read - end -else - raise "Pass intel hex or raw binary as argument to script" -end - -#test_data += ("\xFF" * 64) - -puts "Plug in programmable device now: (waiting)" -sleep 0.25 while Micronucleus.all.length == 0 - -nucleus = Micronucleus.all.first -puts "Attached to device: #{nucleus.inspect}" - -#puts "Attempting to write '#{test_data.inspect}' to first thinklet's program memory" -#puts "Bytes: #{test_data.bytes.to_a.inspect}" -sleep(0.25) # some time to think? -puts "Attempting to write supplied program in to device's memory" -nucleus.program = test_data - -puts "Great! Starting program..." - - -nucleus.finished # let thinklet know it can go do other things now if it likes -puts "All done!" |