2 ## This file is part of INAV.
4 ## INAV is free software. You can redistribute this software
5 ## and/or modify this software under the terms of the
6 ## GNU General Public License as published by the Free Software
7 ## Foundation, either version 3 of the License, or (at your option)
10 ## INAV is distributed in the hope that they will be
11 ## useful, but WITHOUT ANY WARRANTY; without even the implied
12 ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 ## See the GNU General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with this software.
18 ## If not, see <http://www.gnu.org/licenses/>.
23 class Section < Struct.new(:address, :io); end
25 def initialize address = 0, bin_io = nil, start_address = nil
27 @start_address = start_address == true ? address : start_address
28 add_section address, bin_io if bin_io
31 def add_section address, io
32 sections << Section.new(address, io)
36 sections.each { |section| write_section section, io }
37 write_start_linear_address start_address, io if start_address
43 attr_accessor :start_address
47 def calc_crc address, record_type, data
49 sum += (address & 0xFF00) >> 8
50 sum += (address & 0x00FF)
54 sum += data > 0xFFFF ? 4 : 2
55 sum += (data & 0xFF000000) >> 24
56 sum += (data & 0x00FF0000) >> 16
57 sum += (data & 0x0000FF00) >> 8
58 sum += (data & 0x000000FF)
61 sum += data.each_byte.sum
64 ((sum ^ 0xFF) + 1) & 0xFF
67 def write_end_of_file io
71 def write_start_linear_address address, io
72 crc = calc_crc 0, 5, address
73 io.printf ":04000005%08X%02X\n", address, crc
76 def write_extended_linear_address address, io
77 address_msw = (address & 0xffff0000) >> 16
78 crc = calc_crc 0, 4, address_msw
79 io.printf ":02000004%04X%02X\n", address_msw, crc
82 def write_data address, data, io
84 hex_data = data.each_byte.map { |byte| "%02X" % byte }.join
85 crc = calc_crc address, 0, data
86 io.printf ":%02X%04X00%s%02X\n", data.bytesize, address, hex_data, crc
89 def write_section section, io
91 address = section.address
92 while data = section.io.read(16)
93 write_extended_linear_address address, io if (previous_address & 0xFFFF0000) != (address & 0xFFFF0000)
94 previous_address = address
95 write_data address, data, io
96 address += data.bytesize