Updated EZ‐TUNE (markdown)
[inav.wiki.git] / assets / parse_targets.rb
blob922d8f79cd09f600bae433b50b918a36c6ba51f8
1 #!/usr/bin/ruby
2 # coding: utf-8
4 # Parse release targets for PWM allocations etc.
5 # (c) Jonathan Hudson
6 # Public domain or equivalent, e.g. [Zero Clause BSD](https://tldrlegal.com/license/bsd-0-clause-license)
9 require 'find'
10 require 'optparse'
12 def parse_output lines,name
13   pwms=[]
14   n = 0
15   lines.each do |l|
16     if l.match(/T.._USE_((..)*MOTOR|(..)*SERVO|OUTPUT)/)
17       deftims = l.split(',')
18       alloc = deftims[3]
19       allocs = alloc.split('|').collect{|z| z.strip.gsub(/T.._USE_/,'')}
20       allocs.each_with_index do |a,j|
21         if a == 'OUTPUT_AUTO'
22           tm = deftims[0].match(/T..(\d+)/)
23           if !tm.nil?
24             allocs[j] = "AUTO TIMER #{tm[1]}"
25           end
26         end
27       end
28       pwms << allocs.join(', ')
29       n += 1
30     end
31   end
32   pwms
33 end
35 def build_target defs
36   opts=[]
37   File.open(File.join(defs[:name], "target.c")) do |f0|
38     File.open("/tmp/_target.c","w") do |f1|
39       f0.each do |l|
40         next if l.match(/#include/)
41         f1.puts l
42       end
43     end
44   end
45   dshot=false
46   File.open(File.join(defs[:name], "target.h")) do |f0|
47     f0.each do |l|
48       if l.match(/^\s*#define\s+USE_DSHOT/)
49         dshot = true
50       end
51     end
52   end
54   defs[:variants].each do |v|
55     optd = "-D#{v}=1" #(v == defs[:name]) ? '' : "-D#{v}=1"
56     lines = IO.readlines("|gcc #{optd} -E -o- /tmp/_target.c")
57     res = parse_output lines,v
58     opts << {name: v, pwms: res, dshot: dshot, skip: defs[:skip]}
59   end
60   opts
61 end
63 def write_out_md targets, branch
64   now = Time.now.utc.strftime("%F")
65   puts DATA.read % {:now => now, :branch => branch}
66   puts
68   targets.each do |t0|
69     bname = t0[0][:name]
70     t0.each_with_index do |t,i|
71       if i == 0
72         puts "## Board: #{bname}"
73         puts
74         if t[:skip]
75           puts "Board is not a release target."
76         end
77         if t[:dshot]
78           puts "Board is DSHOT enabled."
79         else
80           puts "Board is not DSHOT enabled."
81         end
82         puts
83       end
84       puts "### Target: #{t[:name]}"
85       puts ""
86       puts "| PWM | Usage |"
87       puts "| --- | ----- |"
88       t[:pwms].each_with_index do |p,n|
89         puts "| #{n+1} | #{p} |"
90       end
91       puts
92     end
93   end
94 end
96 def get_targets all=false
97   tlist=[]
98   skip = nil
99   Find.find('./src/main/target') do |f|
100     if m= f.match(/target\/(\w+)\/CMakeLists\.txt/)
101       dnam = m[1]
102       next if dnam == "SITL"
103       vset = {name: dnam, variants: [], skip: nil}
104       File.open(f) do |fh|
105         fh.each do |l|
106           l.chomp!
107           if m = l.match(/^target_\S{2,3}32\S+\((\w+)[\) ]/)
108             bname = m[1]
109             if dnam == bname
110               skip = l.match(/SKIP_RELEASES/)
111               vset[:skip] = !skip.nil?
112             end
113             vset[:variants] << bname
114           end
115         end
116       end
117       if all or skip.nil?
118         tlist << vset  if vset[:name]
119       end
120     end
121   end
122   tlist
125 all = false
126 branch = "master"
127 ARGV.options do |opt|
128   opt.banner = "Usage: parse_targets.rb [options] [root-dir]"
129   opt.on('--branch=BRANCH', 'Use branch)') {|o| branch=o}
130   opt.on('--all', 'Show all targets (not just release targets)') {all=true}
131   opt.on('-?', "--help", "Show this message") {puts opt; exit}
132   begin
133     opt.parse!
134   rescue
135     puts opt ; exit
136   end
139 root = (ARGV[0]||"inav")
141 Dir.chdir(root)
142 alltargets=[]
143 tlist=nil
145 system "git checkout #{branch} >/dev/null"
147 tlist = get_targets all
149 Dir.chdir("src/main/target")
151 tlist.each do |ti|
152   res = build_target(ti)
153   if res
154     alltargets << res
155   end
158 File.open("/tmp/allt.txt", "w") do |fh|
159   fh.puts alltargets
160   alltargets.each do |ta|
161     fh.puts "==> #{ta}"
162   end
165 write_out_md alltargets, branch
167 __END__
168 # INAV Boards, Targets and PWM allocations
170 It can be difficult for an aircraft builder to determine if a particular board / target will meet their needs.
172 In order to offer some guidance, the following list is machine generated from the files under `inav/source/main/target` to provide a list of the options offered by supported boards.
174 The usage is taken directly from the source code, the following interpretation is offered:
176 | Symbol | Interpretation |
177 | ------ | -------------- |
178 | AUTO | Automatic motor / servo allocation |
179 | MOTOR | Motor |
180 | SERVO | Servo |
181 | LED      | LED strip  |
182 | PWM, ANY | Some other PWM function |
184 `AUTO` is used by INAV 7.0 and later. Hardware timer number is shown againt each `AUTO` line; a common function (`MOTOR`, `SERVO`) may be assigned by the user for a particular timer number.
186 `MOTOR`, `SERVO` are shown against a small number of boards where specific allocation is needed.
188 Prior to INAV 7.0 `MC_`, `FW_` prefixes were shown against motors and servos.
190 Note that the following tables only document PWM outputs that have at least a MOTOR or SERVO use. PWM outputs _solely_ supporting other (LED, PWM, ANY)functions are not listed; for those see the manufacter's documentation (or `target.c`).
192 See project [Cli](https://github.com/iNavFlight/inav/blob/master/docs/Cli.md) and [ESC and servo outputs](https://github.com/iNavFlight/inav/blob/master/docs/ESC%%20and%%20servo%%20outputs.md) documentation.
194 *List generated %{now} from the [INAV %{branch} branch](https://github.com/iNavFlight/inav/) by [`parse_targets.rb`](assets/parse_targets.rb). Some targets may not be available in official or prior releases.* **E&OE.**
196 You are strongly advised to check the board documentation as to the suitability of any particular board.
198 In particular, even though a board is marked as 'DSHOT enabled', there is no guarantee that DSHOT will be available on an arbitrary output as its timer may not have DMA enabled.
200 The configurations listed above are those supported by the INAV developers; other configurations may be possible with a custom target. The source tree contains other, unofficial targets that may (or not) work. A full report, including non-release targets may be generated with `parse_targets.rb --all`.
202 Note also that due to the complexity of output options available in INAV, dynamic resource allocation is not available. Paweł Spychalski has published a [video](https://www.youtube.com/watch?v=v4R-pnO4srU) explaining why resource allocation is not supported by INAV; [see also #1154](https://github.com/iNavFlight/inav/issues/1145)