Makefile 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. # Select the board to build for: if not given on the command line,
  2. # then default to pca10040.
  3. BOARD ?= pca10040
  4. ifeq ($(wildcard boards/$(BOARD)/.),)
  5. $(error Invalid BOARD specified)
  6. endif
  7. # If SoftDevice is selected, try to use that one.
  8. SD ?=
  9. SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]')
  10. # TODO: Verify that it is a valid target.
  11. include boards/$(BOARD)/mpconfigboard.mk
  12. ifeq ($(SD), )
  13. # If the build directory is not given, make it reflect the board name.
  14. BUILD ?= build-$(BOARD)
  15. include ../../py/mkenv.mk
  16. else
  17. # If the build directory is not given, make it reflect the board name.
  18. BUILD ?= build-$(BOARD)-$(SD_LOWER)
  19. include ../../py/mkenv.mk
  20. LD_FILES += boards/$(SD_LOWER)_$(SOFTDEV_VERSION).ld
  21. include drivers/bluetooth/bluetooth_common.mk
  22. endif
  23. LD_FILES += boards/memory.ld boards/common.ld
  24. ifneq ($(LD_FILE),)
  25. # Use custom LD file
  26. LD_FILES = $(LD_FILE)
  27. endif
  28. -include boards/$(BOARD)/modules/boardmodules.mk
  29. # qstr definitions (must come before including py.mk)
  30. QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
  31. # include py core make definitions
  32. include ../../py/py.mk
  33. MICROPY_FATFS ?= 0
  34. FATFS_DIR = lib/oofatfs
  35. MPY_CROSS = ../../mpy-cross/mpy-cross
  36. MPY_TOOL = ../../tools/mpy-tool.py
  37. CROSS_COMPILE = arm-none-eabi-
  38. INC += -I.
  39. INC += -I../..
  40. INC += -I$(BUILD)
  41. INC += -I./../../lib/cmsis/inc
  42. INC += -I./modules/machine
  43. INC += -I./modules/ubluepy
  44. INC += -I./modules/music
  45. INC += -I./modules/random
  46. INC += -I./modules/ble
  47. INC += -I./modules/board
  48. INC += -I../../lib/mp-readline
  49. INC += -I./drivers/bluetooth
  50. INC += -I./drivers
  51. INC += -I../../lib/nrfx/
  52. INC += -I../../lib/nrfx/drivers
  53. INC += -I../../lib/nrfx/drivers/include
  54. INC += -I../../lib/nrfx/mdk
  55. INC += -I../../lib/nrfx/hal
  56. MCU_VARIANT_UPPER = $(shell echo $(MCU_VARIANT) | tr '[:lower:]' '[:upper:]')
  57. MCU_SUB_VARIANT_UPPER = $(shell echo $(MCU_SUB_VARIANT) | tr '[:lower:]' '[:upper:]')
  58. # Figure out correct system file to use base on chip sub-variant name.
  59. SYSTEM_C_SRC :=
  60. ifeq ($(MCU_SUB_VARIANT),nrf51822)
  61. SYSTEM_C_SRC += $(addprefix lib/nrfx/mdk/, system_nrf51.c)
  62. NRF_DEFINES += -D$(MCU_VARIANT_UPPER)
  63. else ifeq ($(MCU_SUB_VARIANT),nrf52832)
  64. SYSTEM_C_SRC += $(addprefix lib/nrfx/mdk/, system_nrf52.c)
  65. NRF_DEFINES += -D$(MCU_VARIANT_UPPER)
  66. else ifeq ($(MCU_SUB_VARIANT),nrf52840)
  67. SYSTEM_C_SRC += $(addprefix lib/nrfx/mdk/, system_nrf52840.c)
  68. # Do not pass MCU_VARIANT_UPPER flag, as NRF52 defines NRF52832 only.
  69. endif
  70. NRF_DEFINES += -D$(MCU_SUB_VARIANT_UPPER)
  71. NRF_DEFINES += -DCONFIG_GPIO_AS_PINRESET
  72. CFLAGS_CORTEX_M = -mthumb -mabi=aapcs -fsingle-precision-constant -Wdouble-promotion
  73. CFLAGS_MCU_m4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
  74. CFLAGS_MCU_m0 = $(CFLAGS_CORTEX_M) -fshort-enums -mtune=cortex-m0 -mcpu=cortex-m0 -mfloat-abi=soft -fno-builtin
  75. LTO ?= 1
  76. ifeq ($(LTO),1)
  77. CFLAGS += -flto
  78. else
  79. CFLAGS += -ffunction-sections -fdata-sections
  80. LDFLAGS += -Wl,--gc-sections
  81. endif
  82. CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES))
  83. CFLAGS += $(INC) -Wall -Werror -g -ansi -std=c11 -nostdlib $(COPT) $(NRF_DEFINES) $(CFLAGS_MOD)
  84. CFLAGS += -fno-strict-aliasing
  85. CFLAGS += -Iboards/$(BOARD)
  86. CFLAGS += -DNRF5_HAL_H='<$(MCU_VARIANT)_hal.h>'
  87. LDFLAGS = $(CFLAGS)
  88. LDFLAGS += -Xlinker -Map=$(@:.elf=.map)
  89. LDFLAGS += -mthumb -mabi=aapcs $(addprefix -T,$(LD_FILES)) -L boards/
  90. #Debugging/Optimization
  91. ifeq ($(DEBUG), 1)
  92. #ASMFLAGS += -g -gtabs+
  93. CFLAGS += -O0 -ggdb
  94. LDFLAGS += -O0
  95. else
  96. CFLAGS += -Os -DNDEBUG
  97. LDFLAGS += -Os
  98. endif
  99. LIBS = \
  100. ifeq ($(MCU_VARIANT), nrf52)
  101. LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
  102. LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
  103. SRC_LIB += $(addprefix lib/,\
  104. libm/math.c \
  105. libm/fmodf.c \
  106. libm/nearbyintf.c \
  107. libm/ef_sqrt.c \
  108. libm/kf_rem_pio2.c \
  109. libm/kf_sin.c \
  110. libm/kf_cos.c \
  111. libm/kf_tan.c \
  112. libm/ef_rem_pio2.c \
  113. libm/sf_sin.c \
  114. libm/sf_cos.c \
  115. libm/sf_tan.c \
  116. libm/sf_frexp.c \
  117. libm/sf_modf.c \
  118. libm/sf_ldexp.c \
  119. libm/asinfacosf.c \
  120. libm/atanf.c \
  121. libm/atan2f.c \
  122. )
  123. endif
  124. SRC_LIB += $(addprefix lib/,\
  125. libc/string0.c \
  126. mp-readline/readline.c \
  127. utils/pyexec.c \
  128. utils/interrupt_char.c \
  129. timeutils/timeutils.c \
  130. )
  131. ifeq ($(MICROPY_FATFS), 1)
  132. SRC_LIB += $(addprefix lib/,\
  133. oofatfs/ff.c \
  134. oofatfs/option/unicode.c \
  135. )
  136. endif
  137. SRC_NRFX += $(addprefix lib/nrfx/drivers/src/,\
  138. prs/nrfx_prs.c \
  139. nrfx_uart.c \
  140. nrfx_adc.c \
  141. nrfx_saadc.c \
  142. nrfx_rng.c \
  143. nrfx_twi.c \
  144. nrfx_spi.c \
  145. nrfx_spim.c \
  146. nrfx_rtc.c \
  147. nrfx_timer.c \
  148. nrfx_pwm.c \
  149. nrfx_gpiote.c \
  150. )
  151. SRC_NRFX_HAL += $(addprefix lib/nrfx/hal/,\
  152. nrf_nvmc.c \
  153. )
  154. SRC_C += \
  155. main.c \
  156. mphalport.c \
  157. help.c \
  158. gccollect.c \
  159. pin_named_pins.c \
  160. fatfs_port.c \
  161. drivers/flash.c \
  162. drivers/softpwm.c \
  163. drivers/ticker.c \
  164. drivers/bluetooth/ble_drv.c \
  165. drivers/bluetooth/ble_uart.c \
  166. DRIVERS_SRC_C += $(addprefix modules/,\
  167. machine/modmachine.c \
  168. machine/uart.c \
  169. machine/spi.c \
  170. machine/i2c.c \
  171. machine/adc.c \
  172. machine/pin.c \
  173. machine/timer.c \
  174. machine/rtcounter.c \
  175. machine/pwm.c \
  176. machine/temp.c \
  177. uos/moduos.c \
  178. uos/microbitfs.c \
  179. utime/modutime.c \
  180. board/modboard.c \
  181. board/led.c \
  182. ubluepy/modubluepy.c \
  183. ubluepy/ubluepy_peripheral.c \
  184. ubluepy/ubluepy_service.c \
  185. ubluepy/ubluepy_characteristic.c \
  186. ubluepy/ubluepy_uuid.c \
  187. ubluepy/ubluepy_delegate.c \
  188. ubluepy/ubluepy_constants.c \
  189. ubluepy/ubluepy_descriptor.c \
  190. ubluepy/ubluepy_scanner.c \
  191. ubluepy/ubluepy_scan_entry.c \
  192. music/modmusic.c \
  193. music/musictunes.c \
  194. ble/modble.c \
  195. random/modrandom.c \
  196. )
  197. # Custom micropython startup file with smaller interrupt vector table
  198. # than the file provided in nrfx.
  199. SRC_C += \
  200. device/startup_$(MCU_SUB_VARIANT).c \
  201. ifneq ($(FROZEN_MPY_DIR),)
  202. FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
  203. FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
  204. endif
  205. OBJ += $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
  206. OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
  207. OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
  208. OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o))
  209. OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX_HAL:.c=.o))
  210. OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
  211. OBJ += $(addprefix $(BUILD)/, $(SYSTEM_C_SRC:.c=.o))
  212. OBJ += $(BUILD)/pins_gen.o
  213. $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
  214. $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
  215. .PHONY: all flash sd binary hex
  216. all: binary hex
  217. OUTPUT_FILENAME = firmware
  218. ## Create binary .bin file from the .out file
  219. binary: $(BUILD)/$(OUTPUT_FILENAME).bin
  220. $(BUILD)/$(OUTPUT_FILENAME).bin: $(BUILD)/$(OUTPUT_FILENAME).elf
  221. $(OBJCOPY) -O binary $< $@
  222. ## Create binary .hex file from the .out file
  223. hex: $(BUILD)/$(OUTPUT_FILENAME).hex
  224. $(BUILD)/$(OUTPUT_FILENAME).hex: $(BUILD)/$(OUTPUT_FILENAME).elf
  225. $(OBJCOPY) -O ihex $< $@
  226. FLASHER ?=
  227. ifeq ($(FLASHER),)
  228. flash: $(BUILD)/$(OUTPUT_FILENAME).hex
  229. nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
  230. nrfjprog --reset -f $(MCU_VARIANT)
  231. sd: $(BUILD)/$(OUTPUT_FILENAME).hex
  232. nrfjprog --eraseall -f $(MCU_VARIANT)
  233. nrfjprog --program $(SOFTDEV_HEX) -f $(MCU_VARIANT)
  234. nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
  235. nrfjprog --reset -f $(MCU_VARIANT)
  236. else ifeq ($(FLASHER), pyocd)
  237. flash: $(BUILD)/$(OUTPUT_FILENAME).hex
  238. pyocd-flashtool -t $(MCU_VARIANT) $<
  239. sd: $(BUILD)/$(OUTPUT_FILENAME).hex
  240. pyocd-flashtool -t $(MCU_VARIANT) --chip_erase
  241. pyocd-flashtool -t $(MCU_VARIANT) $(SOFTDEV_HEX)
  242. pyocd-flashtool -t $(MCU_VARIANT) $<
  243. endif
  244. $(BUILD)/$(OUTPUT_FILENAME).elf: $(OBJ)
  245. $(ECHO) "LINK $@"
  246. $(Q)$(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
  247. $(Q)$(SIZE) $@
  248. # List of sources for qstr extraction
  249. SRC_QSTR += $(SRC_C) $(DRIVERS_SRC_C) $(SRC_BOARD_MODULES)
  250. # Append any auto-generated sources that are needed by sources listed in
  251. # SRC_QSTR
  252. SRC_QSTR_AUTO_DEPS +=
  253. # Making OBJ use an order-only depenedency on the generated pins.h file
  254. # has the side effect of making the pins.h file before we actually compile
  255. # any of the objects. The normal dependency generation will deal with the
  256. # case when pins.h is modified. But when it doesn't exist, we don't know
  257. # which source files might need it.
  258. $(OBJ): | $(HEADER_BUILD)/pins.h
  259. # Use a pattern rule here so that make will only call make-pins.py once to make
  260. # both pins_gen.c and pins.h
  261. $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
  262. $(ECHO) "Create $@"
  263. $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC)
  264. $(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
  265. $(call compile_c)
  266. MAKE_PINS = boards/make-pins.py
  267. BOARD_PINS = boards/$(BOARD)/pins.csv
  268. AF_FILE = $(MCU_VARIANT)_af.csv
  269. PREFIX_FILE = boards/$(MCU_VARIANT)_prefix.c
  270. GEN_PINS_SRC = $(BUILD)/pins_gen.c
  271. GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
  272. GEN_PINS_QSTR = $(BUILD)/pins_qstr.h
  273. GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h
  274. GEN_PINS_AF_PY = $(BUILD)/pins_af.py
  275. ifneq ($(FROZEN_DIR),)
  276. # To use frozen source modules, put your .py files in a subdirectory (eg scripts/)
  277. # and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch).
  278. CFLAGS += -DMICROPY_MODULE_FROZEN_STR
  279. endif
  280. ifneq ($(FROZEN_MPY_DIR),)
  281. # To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and
  282. # then invoke make with FROZEN_MPY_DIR=frozen (be sure to build from scratch).
  283. CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
  284. CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
  285. endif
  286. $(PY_BUILD)/nlr%.o: CFLAGS += -Os -fno-lto
  287. include ../../py/mkrules.mk