2 from genericpath
import exists
4 from random
import randint
13 build_flags
= env
.get('BUILD_FLAGS', [])
17 target_name
= env
.get('PIOENV', '').upper()
19 isRX
= True if '_RX_' in target_name
else False
21 def print_error(error
):
23 sys
.stdout
.write("\n\n\033[47;31m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
24 sys
.stdout
.write("\033[47;31m!!! ExpressLRS Warning Below !!!\n")
25 sys
.stdout
.write("\033[47;31m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
26 sys
.stdout
.write("\033[47;30m %s \n" % error
)
27 sys
.stdout
.write("\033[47;31m%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n")
30 raise Exception('!!! %s !!!' % error
)
34 if str[0] == '"' and str[-1] == '"':
38 def process_json_flag(define
):
39 parts
= re
.search(r
"-D(.*)\s*=\s*(.*)$", define
)
40 if parts
and define
.startswith("-D"):
41 if parts
.group(1) == "MY_BINDING_PHRASE":
42 json_flags
['uid'] = [x
for x
in hashlib
.md5(define
.encode()).digest()[0:6]]
43 if parts
.group(1) == "HOME_WIFI_SSID":
44 json_flags
['wifi-ssid'] = dequote(parts
.group(2))
45 if parts
.group(1) == "HOME_WIFI_PASSWORD":
46 json_flags
['wifi-password'] = dequote(parts
.group(2))
47 if parts
.group(1) == "AUTO_WIFI_ON_INTERVAL":
48 parts
= re
.search(r
"-D(.*)\s*=\s*\"?
([0-9]+).*\"?$
", define)
49 json_flags['wifi-on-interval'] = int(dequote(parts.group(2)))
50 if parts.group(1) == "TLM_REPORT_INTERVAL_MS
" and not isRX:
51 parts = re.search(r"-D(.*)\s
*=\s
*\"?
([0-9]+).*\"?$
", define)
52 json_flags['tlm-interval'] = int(dequote(parts.group(2)))
53 if parts.group(1) == "FAN_MIN_RUNTIME
" and not isRX:
54 parts = re.search(r"-D(.*)\s
*=\s
*\"?
([0-9]+).*\"?$
", define)
55 json_flags['fan-runtime'] = int(dequote(parts.group(2)))
56 if parts.group(1) == "RCVR_UART_BAUD
" and isRX:
57 parts = re.search(r"-D(.*)\s
*=\s
*\"?
([0-9]+).*\"?$
", define)
58 json_flags['rcvr-uart-baud'] = int(dequote(parts.group(2)))
59 if parts.group(1) == "USE_AIRPORT_AT_BAUD
":
60 parts = re.search(r"-D(.*)\s
*=\s
*\"?
([0-9]+).*\"?$
", define)
61 json_flags['is-airport'] = True
63 json_flags['rcvr-uart-baud'] = int(dequote(parts.group(2)))
65 json_flags['airport-uart-baud'] = int(dequote(parts.group(2)))
66 if define == "-DUNLOCK_HIGHER_POWER
" and not isRX:
67 json_flags['unlock-higher-power'] = True
68 if define == "-DLOCK_ON_FIRST_CONNECTION
" and isRX:
69 json_flags['lock-on-first-connection'] = True
71 def process_build_flag(define):
72 if define.startswith("-D
") or define.startswith("!-D
"):
73 if "MY_BINDING_PHRASE
" in define:
74 bindingPhraseHash = hashlib.md5(define.encode()).digest()
75 UIDbytes = ",".join(list(map(str, bindingPhraseHash))[0:6])
76 define = "-DMY_UID
=" + UIDbytes
77 sys.stdout.write("\u001b
[32mUID bytes
: " + UIDbytes + "\n")
79 if "MY_STARTUP_MELODY
=" in define:
80 parsedMelody = melodyparser.parse(define.split('"')[1::2][0])
81 define = "-DMY_STARTUP_MELODY_ARR=\"" + parsedMelody + "\""
82 if "HOME_WIFI_SSID=" in define:
83 parts = re.search(r"(.*)=\w*\"(.*)\"$", define)
84 if parts and parts.group(2):
85 define = "-DHOME_WIFI_SSID=" + string_to_ascii(parts.group(2))
86 if "HOME_WIFI_PASSWORD=" in define:
87 parts = re.search(r"(.*)=\w*\"(.*)\"$", define)
88 if parts and parts.group(2):
89 define = "-DHOME_WIFI_PASSWORD=" + string_to_ascii(parts.group(2))
90 if "DEVICE_NAME=" in define:
91 parts = re.search(r"(.*)=\w*'?
\"(.*)\"'?$", define)
92 if parts and parts.group(2):
93 env['DEVICE_NAME
'] = parts.group(2)
94 if not define in build_flags:
95 build_flags.append(define)
97 def parse_flags(path):
101 with open(path, "r") as _f:
103 define = define.strip()
104 process_build_flag(define)
105 process_json_flag(define)
108 print("File '%s' does not exist" % path)
110 def process_flags(path):
112 if not os.path.isfile(path):
116 def condense_flags():
118 for line in build_flags:
119 # Some lines have multiple flags so this will split them and remove them all
120 for flag in re.findall(r"!-D\s*[^\s]+", line):
121 build_flags = [x.replace(flag,"") for x in build_flags] # remove the removal flag
122 build_flags = [x.replace(flag[1:],"") for x in build_flags] # remove the flag if it matches the removal flag
123 build_flags = [x for x in build_flags if (x.strip() != "")] # remove any blank items
125 def version_to_env():
126 ver = elrs_helpers.get_git_version()
127 env.Append(GIT_SHA = ver['sha
'], GIT_VERSION= ver['version
'])
129 def string_to_ascii(str):
130 return ",".join(["%s" % ord(char) for char in str])
133 return string_to_ascii(env.get('GIT_SHA
'))
136 return string_to_ascii(env.get('GIT_VERSION
'))
138 json_flags['flash
-discriminator
'] = randint(1,2**32-1)
139 json_flags['wifi
-on
-interval
'] = -1
141 process_flags("user_defines.txt")
142 process_flags("super_defines.txt") # allow secret super_defines to override user_defines
144 build_flags.append("-DLATEST_COMMIT=" + get_git_sha())
145 build_flags.append("-DLATEST_VERSION=" + get_version())
146 build_flags.append("-DTARGET_NAME=" + re.sub("_VIA_.*", "", target_name))
149 if '-DRADIO_SX127X
=1' in build_flags or '-DRADIO_LR1121
=1' in build_flags:
150 # disallow setting 2400s for 900
151 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_ISM_2400
') or \
152 fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_CE_2400
'):
153 print_error('Regulatory_Domain
2400 not compatible with RADIO_SX127X
/RADIO_LR1121
')
155 # require a domain be set for 900
156 if not fnmatch.filter(build_flags, '*-DRegulatory_Domain
*'):
157 print_error('Please define a Regulatory_Domain
in user_defines
.txt
')
159 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_AU_915
'):
160 json_flags['domain
'] = 0
161 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_FCC_915
'):
162 json_flags['domain
'] = 1
163 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_868
'):
164 json_flags['domain
'] = 2
165 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_IN_866
'):
166 json_flags['domain
'] = 3
167 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_AU_433
'):
168 json_flags['domain
'] = 4
169 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_EU_433
'):
170 json_flags['domain
'] = 5
171 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_US_433
'):
172 json_flags['domain
'] = 6
173 if fnmatch.filter(build_flags, '*-DRegulatory_Domain_US_433_WIDE
'):
174 json_flags['domain
'] = 7
176 json_flags['domain
'] = 0
178 # Remove ISM_2400 domain flag if not unit test, it is defined per target config
179 if fnmatch.filter(build_flags, '*Regulatory_Domain_ISM_2400
*') and \
180 target_name != "NATIVE":
181 build_flags = [f for f in build_flags if "Regulatory_Domain_ISM_2400" not in f]
183 env['OPTIONS_JSON
'] = json_flags
184 env['BUILD_FLAGS
'] = build_flags
185 sys.stdout.write("\nbuild flags: %s\n\n" % build_flags)
187 if fnmatch.filter(build_flags, '*PLATFORM_ESP32
*'):
188 sys.stdout.write("\u001b[32mBuilding for ESP32 Platform\n")
189 elif fnmatch.filter(build_flags, '*PLATFORM_STM32
*'):
190 sys.stdout.write("\u001b[32mBuilding for STM32 Platform\n")
191 elif fnmatch.filter(build_flags, '*PLATFORM_ESP8266
*'):
192 sys.stdout.write("\u001b[32mBuilding for ESP8266/ESP8285 Platform\n")
193 if fnmatch.filter(build_flags, '-DAUTO_WIFI_ON_INTERVAL
*'):
194 sys.stdout.write("\u001b[32mAUTO_WIFI_ON_INTERVAL = ON\n")
196 sys.stdout.write("\u001b[32mAUTO_WIFI_ON_INTERVAL = OFF\n")
201 # Set upload_protovol = 'custom
' for STM32 MCUs
202 # otherwise firmware.bin is not generated
203 stm = env.get('PIOPLATFORM
', '') in ['ststm32
']
205 env['UPLOAD_PROTOCOL
'] = 'custom
'
206 # -DFLASH_DISCRIM=xxxx can't be passed on the command line
or it will every
file to
207 # always be rebuilt, so put it in a header that options.cpp can include
208 print(f
"#define FLASH_DISCRIM {json_flags['flash-discriminator']}",
209 file=open("include/flashdiscrim.h", "w"))