forked from espruino/Espruino
-
Notifications
You must be signed in to change notification settings - Fork 4
/
build_platform_config.py
executable file
·402 lines (348 loc) · 16.1 KB
/
build_platform_config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#!/usr/bin/python
# This file is part of Espruino, a JavaScript interpreter for Microcontrollers
#
# Copyright (C) 2013 Gordon Williams <[email protected]>
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# ----------------------------------------------------------------------------------------
# Reads board information from boards/BOARDNAME.py and uses it to generate a header file
# which describes the available peripherals on the board
# ----------------------------------------------------------------------------------------
import subprocess;
import re;
import json;
import sys;
import os;
import importlib;
import common;
scriptdir = os.path.dirname(os.path.realpath(__file__))
# added os.path.normpath to get a correct reckognition of the subsequent path
# by Ubuntu 14.04 LTS
basedir = os.path.normpath(scriptdir+"/../")
# added leading / as a consequence of use of os.path.normpath
sys.path.append(basedir+"/scripts");
sys.path.append(basedir+"/boards");
import pinutils;
# -----------------------------------------------------------------------------------------
# Now scan AF file
print("Script location "+scriptdir)
if len(sys.argv)!=2:
print("ERROR, USAGE: build_platform_config.py BOARD_NAME")
exit(1)
boardname = sys.argv[1]
headerFilename = "gen/platform_config.h"
print("HEADER_FILENAME "+headerFilename)
print("BOARD "+boardname)
# import the board def
board = importlib.import_module(boardname)
pins = board.get_pins()
# -----------------------------------------------------------------------------------------
LINUX = board.chip["family"]=="LINUX"
if not "default_console" in board.info:
board.info["default_console"] = "EV_SERIAL1"
has_bootloader = False
if "bootloader" in board.info and board.info["bootloader"]!=0:
has_bootloader = True
if not LINUX:
# 100xB and 103xB are mid-density, so have 1k page sizes
if board.chip["part"][:7]=="STM32F1" and board.chip["part"][10]=="B": board.chip["subfamily"]="MD";
# how much room for stack (and EVERYTHING else)
space_for_stack = 4 #kB
if board.chip["ram"] > 20: space_for_stack = 5
variable_storage = board.chip["ram"] - space_for_stack
# work out # of variables
# We need to know if we should be using 8 or 16 bit addresses
#variables_8bit = (variable_storage*1024 ) / 12
#variables_16bit = (variable_storage*1024) / 16
#if variables_8bit > 254 and variables_16bit > 254:
# variables = variables_16bit
#else:
# variables = variables_8bit
# But in some cases we may not have enough flash memory!
variables=board.info["variables"]
var_size = 12 if variables<1023 else 16
# the 'packed bits mean anything under 1023 vars gets into 12 byte JsVars
var_cache_size = var_size*variables
flash_needed = var_cache_size + 4 # for magic number
flash_page_size = 1024 # just a guess
if board.chip["family"]=="STM32F1": flash_page_size = 1024 if "subfamily" in board.chip and board.chip["subfamily"]=="MD" else 2048
if board.chip["family"]=="STM32F2":
flash_page_size = 128*1024
if board.chip["family"]=="STM32F3": flash_page_size = 2*1024
if board.chip["family"]=="STM32F4":
flash_page_size = 128*1024
if board.chip["family"]=="NRF51":
flash_page_size = 1024
if board.chip["family"]=="NRF52":
flash_page_size = 4*1024
if board.chip["family"]=="EFM32GG":
flash_page_size = 4*1024
flash_saved_code_pages = round((flash_needed+flash_page_size-1)/flash_page_size + 0.5) #Needs to be a full page, so we're rounding up
# F4 has different page sizes in different places
total_flash = board.chip["flash"]*1024
if "saved_code" in board.chip:
flash_saved_code_start = board.chip["saved_code"]["address"]
flash_page_size = board.chip["saved_code"]["page_size"]
flash_saved_code_pages = board.chip["saved_code"]["pages"]
flash_available_for_code = board.chip["saved_code"]["flash_available"]*1024
else:
flash_saved_code_start = "(FLASH_START + FLASH_TOTAL - FLASH_SAVED_CODE_LENGTH)"
flash_available_for_code = total_flash - (flash_saved_code_pages*flash_page_size)
if has_bootloader: flash_available_for_code -= common.get_bootloader_size(board)
print("Variables = "+str(variables))
print("JsVar size = "+str(var_size))
print("VarCache size = "+str(var_cache_size))
print("Flash page size = "+str(flash_page_size))
print("Flash pages = "+str(flash_saved_code_pages))
print("Total flash = "+str(total_flash))
print("Flash available for code = "+str(flash_available_for_code))
# -----------------------------------------------------------------------------------------
headerFile = open(headerFilename, 'w')
def codeOut(s): headerFile.write(s+"\n");
# -----------------------------------------------------------------------------------------
def die(err):
print("ERROR: "+err)
sys.exit(1)
def toPinDef(pin):
for p in pins:
if p["name"]=="P"+pin:
return str(pins.index(p))+"/* "+pin+" */";
die("Pin named '"+pin+"' not found");
def codeOutDevice(device):
if device in board.devices:
codeOut("#define "+device+"_PININDEX "+toPinDef(board.devices[device]["pin"]))
if device=="BTN1":
codeOut("#define "+device+"_ONSTATE "+("0" if "inverted" in board.devices[device] else "1"))
if "pinstate" in board.devices[device]:
codeOut("#define "+device+"_PINSTATE JSHPINSTATE_GPIO_"+board.devices[device]["pinstate"]);
def codeOutDevicePin(device, pin, definition_name):
if device in board.devices:
codeOut("#define "+definition_name+" "+toPinDef(board.devices[device][pin]))
# -----------------------------------------------------------------------------------------
codeOut("""
// Automatically generated header file for """+boardname+"""
// Generated by scripts/build_platform_config.py
#ifndef _PLATFORM_CONFIG_H
#define _PLATFORM_CONFIG_H
""");
codeOut("#define PC_BOARD_ID \""+boardname+"\"")
codeOut("#define PC_BOARD_CHIP \""+board.chip["part"]+"\"")
codeOut("#define PC_BOARD_CHIP_FAMILY \""+board.chip["family"]+"\"")
codeOut("")
linker_end_var = "_end";
linker_etext_var = "_etext";
if board.chip["family"]=="LINUX":
board.chip["class"]="LINUX"
elif board.chip["family"]=="STM32F1":
board.chip["class"]="STM32"
codeOut('#include "stm32f10x.h"')
elif board.chip["family"]=="STM32F2":
board.chip["class"]="STM32"
codeOut('#include "stm32f2xx.h"')
codeOut("#define STM32API2 // hint to jshardware that the API is a lot different")
elif board.chip["family"]=="STM32F3":
board.chip["class"]="STM32"
codeOut('#include "stm32f30x.h"')
codeOut("#define STM32API2 // hint to jshardware that the API is a lot different")
codeOut("#define USB_INT_DEFAULT") # hack
elif board.chip["family"]=="STM32F4":
board.chip["class"]="STM32"
codeOut('#include "stm32f4xx.h"')
codeOut('#include "stm32f4xx_conf.h"')
codeOut("#define STM32API2 // hint to jshardware that the API is a lot different")
elif board.chip["family"]=="NRF51":
board.chip["class"]="NRF51"
codeOut('#include "nrf.h"')
elif board.chip["family"]=="NRF52":
board.chip["class"]="NRF52"
codeOut('#include "nrf.h"') # TRY THIS BUT NOT SURE~!
elif board.chip["family"]=="EFM32GG":
linker_etext_var = "__etext";
board.chip["class"]="EFM32"
codeOut('#include "em_device.h"')
elif board.chip["family"]=="LPC1768":
board.chip["class"]="MBED"
elif board.chip["family"]=="AVR":
board.chip["class"]="AVR"
elif board.chip["family"]=="ESP8266":
board.chip["class"]="ESP8266"
else:
die('Unknown chip family '+board.chip["family"])
codeOut("#define LINKER_END_VAR "+linker_end_var);
codeOut("#define LINKER_ETEXT_VAR "+linker_etext_var);
if board.chip["class"]=="MBED":
codeOut("""
#pragma diag_suppress 1295 // deprecated decl
#pragma diag_suppress 188 // enumerated type mixed with another type
#pragma diag_suppress 111 // statement is unreachable
#pragma diag_suppress 68 // integer conversion resulted in a change of sign
""");
codeOut("""
// SYSTICK is the counter that counts up and that we use as the real-time clock
// The smaller this is, the longer we spend in interrupts, but also the more we can sleep!
#define SYSTICK_RANGE 0x1000000 // the Maximum (it is a 24 bit counter) - on Olimexino this is about 0.6 sec
#define SYSTICKS_BEFORE_USB_DISCONNECT 2
#define DEFAULT_BUSY_PIN_INDICATOR (Pin)-1 // no indicator
#define DEFAULT_SLEEP_PIN_INDICATOR (Pin)-1 // no indicator
// When to send the message that the IO buffer is getting full
#define IOBUFFER_XOFF ((TXBUFFERMASK)*6/8)
// When to send the message that we can start receiving again
#define IOBUFFER_XON ((TXBUFFERMASK)*3/8)
""");
if board.chip["class"]=="STM32":
if (board.chip["part"][:9]=="STM32F401") | (board.chip["part"][:9]=="STM32F411"):
# FIXME - need to remove TIM5 from jspininfo
codeOut("""
// Used by various pins, but always with other options
#define UTIL_TIMER TIM5
#define UTIL_TIMER_IRQn TIM5_IRQn
#define UTIL_TIMER_IRQHandler TIM5_IRQHandler
#define UTIL_TIMER_APB1 RCC_APB1Periph_TIM5
""")
elif "subfamily" in board.chip and board.chip["subfamily"]=="MD":
codeOut("""
// frustratingly the 103_MD (non-VL) chips in Olimexino don't have any timers other than 1-4
#define UTIL_TIMER TIM4
#define UTIL_TIMER_IRQn TIM4_IRQn
#define UTIL_TIMER_IRQHandler TIM4_IRQHandler
#define UTIL_TIMER_APB1 RCC_APB1Periph_TIM4
""")
else:
codeOut("""
// nice timer not used by anything else
#define UTIL_TIMER TIM7
#define UTIL_TIMER_IRQn TIM7_IRQn
#define UTIL_TIMER_IRQHandler TIM7_IRQHandler
#define UTIL_TIMER_APB1 RCC_APB1Periph_TIM7
""")
codeOut("");
# ------------------------------------------------------------------------------------- Chip Specifics
codeOut("#define RAM_TOTAL ("+str(board.chip['ram'])+"*1024)")
codeOut("#define FLASH_TOTAL ("+str(board.chip['flash'])+"*1024)")
codeOut("");
if LINUX:
codeOut('#define RESIZABLE_JSVARS // Allocate variables in blocks using malloc')
#codeOut("#define JSVAR_CACHE_SIZE "+str(200)+" // Number of JavaScript variables in RAM")
else:
codeOut("#define JSVAR_CACHE_SIZE "+str(variables)+" // Number of JavaScript variables in RAM")
codeOut("#define FLASH_AVAILABLE_FOR_CODE "+str(int(flash_available_for_code)))
if board.chip["class"]=="EFM32":
codeOut("// FLASH_PAGE_SIZE defined in em_device.h");
else:
codeOut("#define FLASH_PAGE_SIZE "+str(flash_page_size))
if board.chip["family"]=="ESP8266":
codeOut("#define FLASH_START "+hex(0x0))
elif board.chip["family"]=="NRF52" or board.chip["family"]=="NRF51":
codeOut("#define FLASH_START "+hex(0x0))
elif board.chip["class"]=="EFM32":
codeOut("#define FLASH_START FLASH_BASE // FLASH_BASE defined in em_device.h")
else:
codeOut("#define FLASH_START "+hex(0x08000000))
if has_bootloader:
codeOut("#define BOOTLOADER_SIZE "+str(common.get_bootloader_size(board)))
codeOut("#define ESPRUINO_BINARY_ADDRESS "+hex(common.get_espruino_binary_address(board)))
codeOut("")
codeOut("#define FLASH_SAVED_CODE_START "+str(flash_saved_code_start))
codeOut("#define FLASH_SAVED_CODE_LENGTH "+str(int(flash_page_size*flash_saved_code_pages)))
codeOut("#define FLASH_MAGIC_LOCATION (FLASH_SAVED_CODE_START + FLASH_SAVED_CODE_LENGTH - 4)")
codeOut("#define FLASH_MAGIC 0xDEADBEEF")
codeOut("");
codeOut("#define USART_COUNT "+str(board.chip["usart"]))
codeOut("#define SPI_COUNT "+str(board.chip["spi"]))
codeOut("#define I2C_COUNT "+str(board.chip["i2c"]))
codeOut("#define ADC_COUNT "+str(board.chip["adc"]))
codeOut("#define DAC_COUNT "+str(board.chip["dac"]))
codeOut("");
codeOut("#define DEFAULT_CONSOLE_DEVICE "+board.info["default_console"]);
if "default_console_tx" in board.info:
codeOut("#define DEFAULT_CONSOLE_TX_PIN "+toPinDef(board.info["default_console_tx"]))
if "default_console_rx" in board.info:
codeOut("#define DEFAULT_CONSOLE_RX_PIN "+toPinDef(board.info["default_console_rx"]))
if "default_console_baudrate" in board.info:
codeOut("#define DEFAULT_CONSOLE_BAUDRATE "+board.info["default_console_baudrate"])
codeOut("");
if LINUX:
bufferSizeIO = 256
bufferSizeTX = 256
bufferSizeTimer = 16
else:
bufferSizeIO = 64 if board.chip["ram"]<20 else 128
bufferSizeTX = 32 if board.chip["ram"]<20 else 128
bufferSizeTimer = 4 if board.chip["ram"]<20 else 16
if 'util_timer_tasks' in board.info:
bufferSizeTimer = board.info['util_timer_tasks']
codeOut("#define IOBUFFERMASK "+str(bufferSizeIO-1)+" // (max 255) amount of items in event buffer - events take ~9 bytes each")
codeOut("#define TXBUFFERMASK "+str(bufferSizeTX-1)+" // (max 255)")
codeOut("#define UTILTIMERTASK_TASKS ("+str(bufferSizeTimer)+") // Must be power of 2 - and max 256")
codeOut("");
simpleDevices = [
"LED1","LED2","LED3","LED4","LED5","LED6","LED7","LED8",
"BTN1","BTN2","BTN3","BTN4"];
usedPinChecks = ["false"];
ledChecks = ["false"];
btnChecks = ["false"];
for device in simpleDevices:
if device in board.devices:
codeOutDevice(device)
check = "(PIN)==" + toPinDef(board.devices[device]["pin"])
if device[:3]=="LED": ledChecks.append(check)
if device[:3]=="BTN": btnChecks.append(check)
# usedPinChecks.append(check)
# Actually we don't care about marking used pins for LEDs/Buttons
if "USB" in board.devices:
if "pin_disc" in board.devices["USB"]: codeOutDevicePin("USB", "pin_disc", "USB_DISCONNECT_PIN")
if "pin_vsense" in board.devices["USB"]: codeOutDevicePin("USB", "pin_vsense", "USB_VSENSE_PIN")
if "LCD" in board.devices:
if board.devices["LCD"]["controller"]=="fsmc":
for i in range(0,16):
codeOutDevicePin("LCD", "pin_d"+str(i), "LCD_FSMC_D"+str(i))
codeOutDevicePin("LCD", "pin_rd", "LCD_FSMC_RD")
codeOutDevicePin("LCD", "pin_wr", "LCD_FSMC_WR")
codeOutDevicePin("LCD", "pin_cs", "LCD_FSMC_CS")
if "pin_rs" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_rs", "LCD_FSMC_RS")
if "pin_reset" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_reset", "LCD_RESET")
if "pin_bl" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_bl", "LCD_BL")
if board.devices["LCD"]["controller"]=="ssd1306":
codeOutDevicePin("LCD", "pin_mosi", "LCD_SPI_MOSI")
codeOutDevicePin("LCD", "pin_sck", "LCD_SPI_SCK")
codeOutDevicePin("LCD", "pin_cs", "LCD_SPI_CS")
codeOutDevicePin("LCD", "pin_dc", "LCD_SPI_DC")
codeOutDevicePin("LCD", "pin_rst", "LCD_SPI_RST")
if "SD" in board.devices:
if not "pin_d3" in board.devices["SD"]: # NOT SDIO - normal SD
if "pin_cs" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cs", "SD_CS_PIN")
if "pin_di" in board.devices["SD"]: codeOutDevicePin("SD", "pin_di", "SD_DI_PIN")
if "pin_do" in board.devices["SD"]: codeOutDevicePin("SD", "pin_do", "SD_DO_PIN")
if "pin_clk" in board.devices["SD"]:
codeOutDevicePin("SD", "pin_clk", "SD_CLK_PIN")
sdClkPin = pinutils.findpin(pins, "P"+board.devices["SD"]["pin_clk"], False)
spiNum = 0
for func in sdClkPin["functions"]:
if func[:3]=="SPI": spiNum = int(func[3])
if spiNum==0: die("No SPI peripheral found for SD card's CLK pin")
codeOut("#define SD_SPI EV_SPI"+str(spiNum))
for device in ["USB","SD","LCD","JTAG"]:
if device in board.devices:
for entry in board.devices[device]:
if entry[:3]=="pin": usedPinChecks.append("(PIN)==" + toPinDef(board.devices[device][entry])+"/* "+device+" */")
# Specific hacks for nucleo boards
if "NUCLEO_A" in board.devices:
for n,pin in enumerate(board.devices["NUCLEO_A"]):
codeOut("#define NUCLEO_A"+str(n)+" "+toPinDef(pin))
if "NUCLEO_D" in board.devices:
for n,pin in enumerate(board.devices["NUCLEO_D"]):
codeOut("#define NUCLEO_D"+str(n)+" "+toPinDef(pin))
codeOut("")
codeOut("// definition to avoid compilation when Pin/platform config is not defined")
codeOut("#define IS_PIN_USED_INTERNALLY(PIN) (("+")||(".join(usedPinChecks)+"))")
codeOut("#define IS_PIN_A_LED(PIN) (("+")||(".join(ledChecks)+"))")
codeOut("#define IS_PIN_A_BUTTON(PIN) (("+")||(".join(btnChecks)+"))")
codeOut("""
#endif // _PLATFORM_CONFIG_H
""");