PROJECT_NAME     := biketracker_app
TARGETS          := app
OUTPUT_DIRECTORY := _build

FAMILY = NRF52
DEVICE = nrf52832

SOFTDEVICE = $(SDK_ROOT)/components/softdevice/s132/hex/s132_nrf52_4.0.2_softdevice.hex

SDK_ROOT := $(HOME)/dev/nRF5_SDK_13.0.0_04a0bfd
PROJ_DIR := ..

$(OUTPUT_DIRECTORY)/app.out: \
  LINKER_SCRIPT := ./app_gcc_nrf52.ld

# Source files common to all targets
SRC_FILES += \
  $(PROJ_DIR)/acc_kionix_ktxj2.c \
  $(PROJ_DIR)/ble_bts.c \
  $(PROJ_DIR)/ble_periph.c \
  $(PROJ_DIR)/error.c \
  $(PROJ_DIR)/gps_antenova_m10478.c \
  $(PROJ_DIR)/io_ti_tca6424a.c \
  $(PROJ_DIR)/leds.c \
  $(PROJ_DIR)/log_backend.c \
  $(PROJ_DIR)/main.c \
  $(PROJ_DIR)/modem_td1207.c \
  $(PROJ_DIR)/nmea.c \
  $(PROJ_DIR)/power.c \
  $(PROJ_DIR)/state.c \
  $(PROJ_DIR)/tests.c \
  $(PROJ_DIR)/tracking.c \
  $(PROJ_DIR)/util.c \
  $(SDK_ROOT)/components/ble/ble_advertising/ble_advertising.c \
  $(SDK_ROOT)/components/ble/common/ble_advdata.c \
  $(SDK_ROOT)/components/ble/common/ble_conn_state.c \
  $(SDK_ROOT)/components/ble/common/ble_conn_params.c \
  $(SDK_ROOT)/components/ble/common/ble_srv_common.c \
  $(SDK_ROOT)/components/ble/ble_services/ble_dfu/ble_dfu.c \
  $(SDK_ROOT)/components/ble/ble_services/ble_nus/ble_nus.c \
  $(SDK_ROOT)/components/ble/ble_services/ble_tps/ble_tps.c \
  $(SDK_ROOT)/components/ble/peer_manager/gatt_cache_manager.c \
  $(SDK_ROOT)/components/ble/peer_manager/gatts_cache_manager.c \
  $(SDK_ROOT)/components/ble/peer_manager/id_manager.c \
  $(SDK_ROOT)/components/ble/peer_manager/peer_data_storage.c \
  $(SDK_ROOT)/components/ble/peer_manager/peer_database.c \
  $(SDK_ROOT)/components/ble/peer_manager/peer_id.c \
  $(SDK_ROOT)/components/ble/peer_manager/peer_manager.c \
  $(SDK_ROOT)/components/ble/peer_manager/pm_buffer.c \
  $(SDK_ROOT)/components/ble/peer_manager/pm_mutex.c \
  $(SDK_ROOT)/components/ble/peer_manager/security_manager.c \
  $(SDK_ROOT)/components/ble/peer_manager/security_dispatcher.c \
  $(SDK_ROOT)/components/drivers_nrf/saadc/nrf_drv_saadc.c \
  $(SDK_ROOT)/components/drivers_nrf/clock/nrf_drv_clock.c \
  $(SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c \
  $(SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \
  $(SDK_ROOT)/components/drivers_nrf/twi_master/nrf_drv_twi.c \
  $(SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \
  $(SDK_ROOT)/components/drivers_nrf/hal/nrf_nvmc.c \
  $(SDK_ROOT)/components/libraries/bootloader/dfu/nrf_dfu_flash.c \
  $(SDK_ROOT)/components/libraries/bootloader/dfu/nrf_dfu_settings.c \
  $(SDK_ROOT)/components/libraries/crc32/crc32.c \
  $(SDK_ROOT)/components/libraries/fds/fds.c \
  $(SDK_ROOT)/components/libraries/fifo/app_fifo.c \
  $(SDK_ROOT)/components/libraries/fstorage/fstorage.c \
  $(SDK_ROOT)/components/libraries/gpiote/app_gpiote.c \
  $(SDK_ROOT)/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c \
  $(SDK_ROOT)/components/libraries/hardfault/hardfault_implementation.c \
  $(SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \
  $(SDK_ROOT)/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c \
  $(SDK_ROOT)/components/libraries/scheduler/app_scheduler.c \
  $(SDK_ROOT)/components/libraries/timer/app_timer.c \
  $(SDK_ROOT)/components/libraries/twi/app_twi.c \
  $(SDK_ROOT)/components/libraries/uart/app_uart_fifo.c \
  $(SDK_ROOT)/components/libraries/util/app_error.c \
  $(SDK_ROOT)/components/libraries/util/app_util_platform.c \
  $(SDK_ROOT)/components/libraries/util/sdk_mapped_flags.c \
  $(SDK_ROOT)/components/softdevice/common/softdevice_handler/softdevice_handler.c \
  $(SDK_ROOT)/components/toolchain/system_nrf51.c \
  $(SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf51.S \
  $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
  $(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \

# Include folders common to all targets
INC_FOLDERS += \
  $(PROJ_DIR) \
  . \
  $(SDK_ROOT)/components/ble/common \
  $(SDK_ROOT)/components/ble/ble_advertising \
  $(SDK_ROOT)/components/ble/ble_services/ble_dfu \
  $(SDK_ROOT)/components/ble/ble_services/ble_nus \
  $(SDK_ROOT)/components/ble/ble_services/ble_tps \
  $(SDK_ROOT)/components/ble/peer_manager \
  $(SDK_ROOT)/components/device \
  $(SDK_ROOT)/components/libraries/crc32 \
  $(SDK_ROOT)/components/libraries/bootloader/dfu \
  $(SDK_ROOT)/components/libraries/experimental_section_vars \
  $(SDK_ROOT)/components/libraries/fds \
  $(SDK_ROOT)/components/libraries/fifo \
  $(SDK_ROOT)/components/libraries/fstorage \
  $(SDK_ROOT)/components/libraries/gpiote \
  $(SDK_ROOT)/components/libraries/hardfault/nrf51/handler \
  $(SDK_ROOT)/components/libraries/log \
  $(SDK_ROOT)/components/libraries/log/src \
  $(SDK_ROOT)/components/libraries/pwr_mgmt \
  $(SDK_ROOT)/components/libraries/queue \
  $(SDK_ROOT)/components/libraries/scheduler \
  $(SDK_ROOT)/components/libraries/strerror \
  $(SDK_ROOT)/components/libraries/timer \
  $(SDK_ROOT)/components/libraries/twi \
  $(SDK_ROOT)/components/libraries/uart \
  $(SDK_ROOT)/components/libraries/util \
  $(SDK_ROOT)/components/drivers_nrf/saadc \
  $(SDK_ROOT)/components/drivers_nrf/clock \
  $(SDK_ROOT)/components/drivers_nrf/delay \
  $(SDK_ROOT)/components/drivers_nrf/gpiote \
  $(SDK_ROOT)/components/drivers_nrf/common \
  $(SDK_ROOT)/components/drivers_nrf/twi_master \
  $(SDK_ROOT)/components/drivers_nrf/uart \
  $(SDK_ROOT)/components/drivers_nrf/hal \
  $(SDK_ROOT)/components/softdevice/common/softdevice_handler \
  $(SDK_ROOT)/components/softdevice/s132/headers \
  $(SDK_ROOT)/components/softdevice/s132/headers/nrf52 \
  $(SDK_ROOT)/components/toolchain \
  $(SDK_ROOT)/components/toolchain/cmsis/include \
  $(SDK_ROOT)/external/segger_rtt \

# Libraries common to all targets
LIB_FILES += \

# Application revision. DFU uses this to determine whether the firmware in the mobile app is newer than the firmware on the device. Each value is two hex digits.
APP_REV_MAJOR = 00
APP_REV_MINOR = 01
CFLAGS += -DAPP_REV_MAJOR=$(APP_REV_MAJOR)
CFLAGS += -DAPP_REV_MINOR=$(APP_REV_MINOR)

# Uncomment one and only one of the below BUILD_* -D flags at a time. They control our behaviour on errors and our logging and in some cases cut the build size down massively by leaving stuff out.

# We have the following amount of flash memory available for our application and bootloader:
#   total - (SD + MBR) - (bootloader settings) = app + bootloader
#     256 - (104 + 4)  - 1                     = 147

# For production code we:
#   * Leave all debug LED operations out of the build, but continue to do logging.
#   * Reset immediately on all asserts and faults.
# Currently ~125.6 kB, leaving ~21.5 kB for the bootloader, which is fine.
CFLAGS += -DBUILD_PROD

# For testing in the field we:
#   * Send all NRF_LOG_DEBUG() statements over BLE to the mobile app when in a BLE connection.
#   * Pause on all asserts and faults for 10s so that we notice the assert when on the bike, then reset, so that we can keep testing.
#   * Track even when we're in a BLE connection, so that we can show debugging info on the mobile app UI.
# Currently ~??? kB
#CFLAGS += -DBUILD_FIELD_TEST

# For testing on the desk we:
#   * Block on all asserts and faults so that we can get a stack trace in gdb.
# Currently ~128.6 kB
# The DEBUG, NRF_DEBUG and NRF_DEBUG_USER flags affect how the SDK handles errors. In general, we want these in for desk testing and out for field testing and prod.
#CFLAGS += -DBUILD_DESK_TEST
#CFLAGS += -DDEBUG
#CFLAGS += -DNRF_DEBUG
#CFLAGS += -DNRF_DEBUG_USER

# For debugging the bootloader, we need a much bigger bootloader and therefore a much smaller application. Cut out all the tracking stuff so we can still test DFU OTA, but can't really use the application in the field.
# Currently ~113.8 kB, leaving ~33.2 kB for the debug bootloader, which is fine.
#CFLAGS += -DBUILD_DFU_TEST
#CFLAGS += -DDEBUG
#CFLAGS += -DNRF_DEBUG
#CFLAGS += -DNRF_DEBUG_USER

# C flags common to all targets
CFLAGS += -DBOARD_CUSTOM
CFLAGS += -DSOFTDEVICE_PRESENT
CFLAGS += -DSWI_DISABLE0
CFLAGS += -D__HEAP_SIZE=0
CFLAGS += -DNRF52
CFLAGS += -DNRF52832_XXAA
CFLAGS += -DNRF52_PAN_12
CFLAGS += -DNRF52_PAN_15
CFLAGS += -DNRF52_PAN_20
CFLAGS += -DNRF52_PAN_31
CFLAGS += -DNRF52_PAN_36
CFLAGS += -DNRF52_PAN_51
CFLAGS += -DNRF52_PAN_54
CFLAGS += -DNRF52_PAN_55
CFLAGS += -DNRF52_PAN_58
CFLAGS += -DNRF52_PAN_64
CFLAGS += -DNRF52_PAN_74
CFLAGS += -DS132
CFLAGS += -DBLE_STACK_SUPPORT_REQD
CFLAGS += -DNRF_SD_BLE_API_VERSION=4
CFLAGS += -DNRF_DFU_SETTINGS_VERSION=1
CFLAGS += -mcpu=cortex-m4
CFLAGS += -mthumb -mabi=aapcs
CFLAGS += -Wall -Werror
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16

# Keep every function in separate section. This allows linker to discard unused ones.
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin --short-enums

# Link time optimisation can mess with gdb. Leave it out, except perhaps in a prod build.
# CFLAGS += -flto

# Generate dependency output file
CFLAGS += -MP -MD

# Optimisation levels. See: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
#   -O0:    Reduce compilation time and make debugging produce the expected results. This is the default.
#   -O1:    Optimize [for runtime speed]. Optimizing compilation takes somewhat more time, and a lot more memory for a large function.
#   -O2:    Optimize even more.
#   -O3:    Optimize yet more.
#   -Os:    Optimize for size.
#   -Ofast: Disregard strict standards compliance.
#   -Og:    Optimize debugging experience.
# CFLAGS += -O0: region `FLASH' overflowed by 256 bytes
# CFLAGS += -O1: OK for size.
# CFLAGS += -O3: OK for size.
# CFLAGS += -Os: OK for size.
# CFLAGS += -Og: OK for size. Still seeing <optimized out> on a bunch of variables in a stack trace in gdb though.
CFLAGS += -Og

# Build debuggable code, at the cost of size. Level 3 includes extra information, such as all the macro definitions present in the program.
CFLAGS += -g3

# C++ flags common to all targets
CXXFLAGS += \

# Assembler flags common to all targets
ASMFLAGS += -x assembler-with-cpp
ASMFLAGS += -DBOARD_CUSTOM
ASMFLAGS += -DSOFTDEVICE_PRESENT
ASMFLAGS += -DSWI_DISABLE0
ASMFLAGS += -D__HEAP_SIZE=0
ASMFLAGS += -DNRF52
ASMFLAGS += -DNRF52832_XXAA
ASMFLAGS += -DNRF52_PAN_12
ASMFLAGS += -DNRF52_PAN_15
ASMFLAGS += -DNRF52_PAN_20
ASMFLAGS += -DNRF52_PAN_31
ASMFLAGS += -DNRF52_PAN_36
ASMFLAGS += -DNRF52_PAN_51
ASMFLAGS += -DNRF52_PAN_54
ASMFLAGS += -DNRF52_PAN_55
ASMFLAGS += -DNRF52_PAN_58
ASMFLAGS += -DNRF52_PAN_64
ASMFLAGS += -DNRF52_PAN_74
ASMFLAGS += -DS132
ASMFLAGS += -DBLE_STACK_SUPPORT_REQD
ASMFLAGS += -DNRF_SD_BLE_API_VERSION=4
ASMFLAGS += -DNRF_DFU_SETTINGS_VERSION=1

# Linker flags
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m4
LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# Let linker dump unused sections
LDFLAGS += -Wl,--gc-sections
# Use newlib in nano version
LDFLAGS += --specs=nano.specs -lc -lnosys
# Bike Tracker: Link in support for floats in *printf functions. We use sprintf() and sscanf(). This is NOT the right place to link in libm (math.h).
LDFLAGS += -u _printf_float
LDFLAGS += -u _scanf_float

.PHONY: $(TARGETS) default all clean help flash flash_softdevice

# Default target - first one defined
default: app

TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc

include $(TEMPLATE_PATH)/Makefile.common
$(foreach target, $(TARGETS), $(call define_target, $(target)))
-include $(foreach target, $(TARGETS), $($(target)_dependencies))

# Bike Tracker custom Makefile with our targets
include $(PROJ_DIR)/../Makefile.custom
