# Copyright 2021 John-Mark Gurney. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # ARMOBJDUMP?= arm-none-eabi-objdump ARMCC?= arm-none-eabi-gcc ARMTARGET?= -mcpu=cortex-m3 -mthumb -DSTROBE_SINGLE_THREAD=1 # Clang doesn't work due to no-nano libc #ARMCC?=clang-mp-9.0 #ARMTARGET?= -nostdlib -ffreestanding -target arm-none-eabi -mcpu=cortex-m3 -mfloat-abi=soft -mthumb .if $(.OBJDIR) == $(.CURDIR) .error Need to set MAKEOBJDIR. .endif PLATFORM != uname -s .if $(PLATFORM) == "Darwin" SOEXT=dylib .else .error Unsupported platform: $(PLATFORM) .endif PROGEXT = .elf PROGS = lora.gw lora.irr SRCS.lora.gw = main.c SRCS.lora.irr = irr_main.c SRCS.lora.irr+= comms.c SRCS.lora.irr+= strobe_rng_init.c SRCS.lora.irr+= $(STROBE_SRCS) SRCS+= board.c SRCS+= misc.c .if 0 SRCS+= rng_save.c .endif CFLAGS+= -I$(.CURDIR) CFLAGS+= -g #CFLAGS+= -DNDEBUG CFLAGS+= -I$(.OBJDIR) # for shared_key.h # Strobe .PATH: $(.CURDIR)/strobe CFLAGS+= -I$(.CURDIR)/strobe STROBE_SRCS+= strobe.c \ x25519.c # LoRamac (SX1276) radio code LORAMAC_SRC = $(.CURDIR)/loramac/src .PATH: $(LORAMAC_SRC)/radio/sx1276 $(LORAMAC_SRC)/system $(LORAMAC_SRC)/boards/mcu $(LORAMAC_SRC)/boards/NucleoL152 CFLAGS+= -I$(LORAMAC_SRC)/boards CFLAGS+= -I$(LORAMAC_SRC)/system CFLAGS+= -I$(LORAMAC_SRC)/radio CFLAGS+= -DUSE_HAL_DRIVER -DSX1276MB1LAS SRCS+= sx1276.c SRCS+= utilities.c SRCS+= adc.c timer.c delay.c gpio.c uart.c fifo.c SRCS+= adc-board.c delay-board.c gpio-board.c rtc-board.c lpm-board.c sx1276mb1las-board.c spi-board.c uart-board.c # Microcontroller STM32=$(.CURDIR)/stm32 .PATH: $(STM32)/l151ccux LINKER_SCRIPT=$(STM32)/l151ccux/STM32L151CCUX_FLASH.ld SRCS+= \ startup_stm32l151ccux.s \ stm32l1xx_hal.c \ stm32l1xx_hal_adc.c \ stm32l1xx_hal_adc_ex.c \ stm32l1xx_hal_cortex.c \ stm32l1xx_hal_dma.c \ stm32l1xx_hal_flash.c \ stm32l1xx_hal_flash_ex.c \ stm32l1xx_hal_gpio.c \ stm32l1xx_hal_pcd.c \ stm32l1xx_hal_pcd_ex.c \ stm32l1xx_hal_pwr.c \ stm32l1xx_hal_pwr_ex.c \ stm32l1xx_hal_rcc.c \ stm32l1xx_hal_rcc_ex.c \ stm32l1xx_hal_rtc.c \ stm32l1xx_hal_rtc_ex.c \ stm32l1xx_hal_spi.c \ stm32l1xx_hal_uart.c \ system_stm32l1xx.c SRCS+= \ stm32l1xx_it.c \ stm32l1xx_hal_msp.c CFLAGS+= -I$(STM32) CFLAGS+= -I$(STM32)/l151ccux CFLAGS+= -DSTM32L151xC # USB .PATH: $(STM32)/usb SRCS+= \ stm32l1xx_ll_usb.c \ usb_device.c \ usbd_cdc.c \ usbd_cdc_if.c \ usbd_conf.c \ usbd_core.c \ usbd_ctlreq.c \ usbd_desc.c \ usbd_ioreq.c CFLAGS+= -I$(STM32)/usb CFLAGS+= -Werror -Wall LIBLORA_TEST_SRCS= comms.c strobe.c x25519.c LIBLORA_TEST_OBJS= $(LIBLORA_TEST_SRCS:C/.c$/.no/) LIBLORA_TEST = liblora_test.$(SOEXT) $(LIBLORA_TEST): $(LIBLORA_TEST_OBJS) $(CC) -shared -o $@ $(.ALLSRC) .MAIN: all .PHONY: all DEPENDS = .arm_deps .test_deps .PHONY: $(DEPENDS) depend: $(DEPENDS) .for i in $(DEPENDS) .sinclude "$i" .endfor # Temporarily disabled as OpenOCD can't program EEPROM on the STM32L1. # This could be used to add the data to flash. rng_save.c: Makefile ( echo '#include '; \ echo 'const rng_word_t rng_save[roundup(32, sizeof(rng_word_t)) / sizeof(rng_word_t)] __attribute__ ((section (".eeprom"))) = {'; \ dd if=/dev/random bs=32 count=1 | hexdump -e '4/4 " %3u," "\n"'; \ echo '};' \ ) > $@ || (rm $@ && false) .arm_deps: $(ARMCC) $(ARMTARGET) $(CFLAGS) $(.ALLSRC) -MM > $@ || (rm -f $@ && false) .test_deps: $(LIBLORA_TEST_SRCS) $(CC) $(CFLAGS) $(.ALLSRC) -MM | sed -e 's/\.o:/\.no:/' > $@ || (rm -f $@ && false) .for i in $(PROGS) ALLTGTS+= $(i)$(PROGEXT) $(i).list ASRCS.$(i) = $(SRCS) $(SRCS.$(i)) OBJS.$(i) = $(ASRCS.$(i):C/.c$/.o/) .arm_deps: $(ASRCS.$(i)) $(i)$(PROGEXT) $(i).map: $(OBJS.$(i)) $(ARMCC) $(ARMTARGET) -o $(i)$(PROGEXT) $(.ALLSRC) -T$(LINKER_SCRIPT) --specs=nosys.specs -Wl,-Map="$(i).map" -Wl,--gc-sections -static --specs=nano.specs -Wl,--start-group -lc -lm -Wl,--end-group $(i).list: $(i)$(PROGEXT) $(ARMOBJDUMP) -h -S $(.ALLSRC) > $@ || (rm -f $@ && false) .endfor all: $(ALLTGTS) .PHONY: runbuild runbuild: $(SRCS) for i in $(.MAKEFILE_LIST) $(.ALLSRC) $$(cat $(DEPENDS) | gsed ':x; /\\$$/ { N; s/\\\n//; tx }' | sed -e 's/^[^:]*://'); do if [ "$$i" != ".." ]; then echo $$i; fi; done | sort -u | entr -d sh -c 'echo starting...; cd $(.CURDIR) && $(MAKE) $(.MAKEFLAGS) depend && $(MAKE) $(.MAKEFLAGS) all' .PHONY: runtests runtests: Makefile lora_comms.py lora.py loraserv.py multicast.py $(LIBLORA_TEST) $(LIBLORA_TEST_SRCS) ls $(.ALLSRC) | entr sh -c '(cd $(.CURDIR) && $(MAKE) $(.MAKEFLAGS) $(LIBLORA_TEST)) && ((PYTHONPATH="$(.CURDIR)" python3 -m coverage run -m unittest lora multicast loraserv && coverage report --omit=$(.CURDIR)/p/\* -m -i) 2>&1 | head -n 30)' .if empty(IRR_KEY) && exists($(.CURDIR)/.irr_key) IRR_KEY!= cat $(.CURDIR)/.irr_key .endif .PHONY: irrigation_key irrigation_key: @LANG=C tr -c -d a-zA-Z0-9 < /dev/urandom | dd bs=1 of=$(.CURDIR)/.irr_key count=32 2>/dev/null @echo 'Irrgation key created and put into .irr_key.' # make this a phony target so it's always run # dependancies will only be made when it's updated .PHONY: $(.OBJDIR)/shared_key.h $(.OBJDIR)/shared_key.h: @if [ "$(IRR_KEY)" = "" ]; then echo 'Must provide IRR_KEY make variable or have a non-empty file ".irr_key".'; false; fi @echo 'static uint8_t shared_key[] = {' $$(python3 -c 'import sys; print(", ".join(str(x) for x in sys.argv[1].encode("utf-8")))' $(IRR_KEY) ) "};" > shared_key.h.tmp @echo 'static struct pktbuf shared_key_buf = (struct pktbuf){ .pkt = shared_key, .pktlen = sizeof shared_key, };' >> shared_key.h.tmp (cmp shared_key.h.tmp shared_key.h >/dev/null 2>&1 && rm shared_key.h.tmp) || mv shared_key.h.tmp shared_key.h # native objects .SUFFIXES: .no .c.no: $(CC) $(CFLAGS) -c $< -o $@ .c.o: $(ARMCC) $(ARMTARGET) $(CFLAGS) -c $< -o $@ STROBE_NAME = strobe STROBE_REPO = https://git.code.sf.net/p/strobe/code STROBE_BRANCH = master LORAMAC_NAME = loramac LORAMAC_REPO = https://github.com/Lora-net/LoRaMac-node.git LORAMAC_BRANCH = master .for module in STROBE LORAMAC .PHONY: init-$($(module)_NAME) init-$($(module)_NAME): git subtree add -P $($(module)_NAME) --squash $($(module)_REPO) $($(module)_BRANCH) .PHONY: update-$($(module)_NAME) update-$($(module)_NAME): git subtree pull -P $($(module)_NAME) --squash $($(module)_REPO) $($(module)_BRANCH) .endfor # Making diagrams, imported from fbsdembdev # ========================================= # https://github.com/ironcamel/Graph-Easy .SUFFIXES: .getxt .diag .html .getxt.diag: box.sh graph-easy < $< | sh $(.CURDIR)/box.sh > $@ .diag.html: (cat $<; echo; echo '') > $@ DIAG?=diag test-diag: ls $(.CURDIR)/box.sh $(.CURDIR)/$(DIAG).getxt $(.CURDIR)/Makefile | entr sh -c 'cd $(.CURDIR) && $(MAKE) $(.MAKEFLAGS) $(DIAG).diag && cat $(.OBJDIR)/$(DIAG).diag' # hard coded dependancy for when "make depend" has not been run. irr_main.o: $(.OBJDIR)/shared_key.h