diff --git a/device.rb b/device.rb index 54a39fc..02d139e 100644 --- a/device.rb +++ b/device.rb @@ -6,13 +6,13 @@ module Device class << self - def detect(adiv5) + def detect(adiv5, magic_halt=false) Log(:device, 1){ "detecting device" } ret = NRF51.detect(adiv5) if !ret - ret = Kinetis.detect(adiv5) + ret = Kinetis.detect(adiv5, magic_halt) end if !ret @@ -25,4 +25,4 @@ def detect(adiv5) end -end \ No newline at end of file +end diff --git a/flash.rb b/flash.rb index bcc12c5..5fa3646 100644 --- a/flash.rb +++ b/flash.rb @@ -3,16 +3,32 @@ require 'device' require 'backend-driver' +if ARGV[1] == '--version' + $stdout.puts "McHCK Programmer (Input Club edition)" + exit +end + $stderr.puts "Attaching debugger..." adiv5 = Adiv5.new(BackendDriver.from_string(ARGV[0])) -k = Device.detect(adiv5) +k = nil -if ARGV[1] == '--mass-erase' +if ARGV[1] == '--detect' + k = Device.detect(adiv5, true) # Reset may not work properly for mass erase if chip already flashed + $stdout.puts k.desc + exit +elsif ARGV[1] == '--detect2file' + k = Device.detect(adiv5, true) # Reset may not work properly for mass erase if chip already flashed + $stdout.puts k.desc + File.open('/tmp/detectlog.log', 'w') { |file| file.write(k.detect_info) } + exit +elsif ARGV[1] == '--mass-erase' + k = Device.detect(adiv5, true) # Reset may not work properly for mass erase if chip already flashed $stderr.puts "done." $stderr.puts "Mass erasing chip..." k.mass_erase $stderr.puts "done." else + k = Device.detect(adiv5) $stderr.puts "done." firmware = File.read(ARGV[1], :mode => 'rb') diff --git a/kinetis.rb b/kinetis.rb index 1e2da3b..009dc9d 100644 --- a/kinetis.rb +++ b/kinetis.rb @@ -3,6 +3,9 @@ require 'register' class KinetisBase < ARMv7 + attr_reader :desc + attr_reader :detect_info + def initialize(adiv5) super(adiv5) @mdmap = adiv5.ap(1) @@ -236,11 +239,27 @@ class Flash_Config_Field end end + class SCB + include Peripheral + + default_address 0xE000ED00 + + unsigned :CPUID_RAW, 0x00 + register :CPUID, 0x00 do + unsigned :IMPLEMENTOR, 31..24 + unsigned :VARIANT, 23..20 + unsigned :ARCH, 19..16 + unsigned :PARTNO, 15..4 + unsigned :REV, 3..0 + end + end + class SIM include Peripheral default_address 0x40047000 + unsigned :SOPT_RAW, 0x00 register :SOPT, 0x00 do bool :USBREGEN, 31 bool :USBSSTBY, 30 @@ -377,6 +396,7 @@ class SIM } end + unsigned :SDID_RAW, 0x1024 register :SDID, 0x1024 do unsigned :REVID, 15..12 unsigned :DIEID, 11..7 @@ -440,6 +460,7 @@ class SIM unsigned :USBFRAC, 0 end + unsigned :FCFG1_RAW, 0x104c register :FCFG1, 0x104c do enum :NVMSIZE, 31..28, { 0 => 0b0000, @@ -514,11 +535,11 @@ class SIM } } - def self.detect(adiv5) + def self.detect(adiv5, magic_halt) mdmap = adiv5.ap(1) if mdmap && mdmap.IDR.to_i == 0x001c0000 Log(:Kinetis, 1) {"Detected Kinetis."} - return Kinetis.new(adiv5) + return Kinetis.new(adiv5, magic_halt) end return nil end @@ -542,9 +563,25 @@ def initialize(adiv5, magic_halt=false) @ftfl = Kinetis::FTFL.new(@dap) @flexram = Kinetis::FlexRAM.new(@dap) @sim = Kinetis::SIM.new(@dap) + @scb = Kinetis::SCB.new(@dap) + + Log(:kinetis, 1){ "SIM_SOPT1 " + sprintf("0x%08x", @sim.SOPT_RAW) } + Log(:kinetis, 1){ "SIM_SDID " + sprintf("0x%08x", @sim.SDID_RAW) } + Log(:kinetis, 1){ "SIM_FCFG1 " + sprintf("0x%08x", @sim.FCFG1_RAW) } + Log(:kinetis, 1){ "SCB_CPUID " + sprintf("0x%08x", @scb.CPUID_RAW) } + + @detect_info = sprintf( +"SIM_SOPT1: : %08x +SIM_SDID : : %08x +SIM_FCFG1: : %08x +SCB_CPUID: : %08x +", @sim.SOPT_RAW, @sim.SDID_RAW, @sim.FCFG1_RAW, @scb.CPUID_RAW) + + # Use FAMID and DIEID to determine which kinetis MCU flash_key = @sim.SDID.FAMID | (@sim.SDID.DIEID << 3); if FlashConfig.has_key?(flash_key) Log(:kinetis, 1){ "detected " + FlashConfig[flash_key][:desc] } + @desc = FlashConfig[flash_key][:desc] @sector_size = FlashConfig[flash_key][:sector_size] @sector_blocks = FlashConfig[flash_key][:sector_blocks] @phrase_size = FlashConfig[flash_key][:phrase_size]