powerpic
Replacement board for a Casio CA-53W
###############################################################################
# Firmware Configuration #
## List of modes to compile
MODES := clock timer power uptime alarmclock settings
## External mode file
MODE_FILE := src/modes/modes.cfg
## PCB Major version number
PCB_REV := 2
## Set the log level 0-4 [Disabled, Error, Warning, Info, Debug]
LOG_LVL := 0
## Frequency of the clock in Hz
XTAL_FREQ := 4000000
## Bootloader offset in hex
BOOT_OFFSET := 0x400
## Date
DT_DATE := $(shell printf ' -DDTINIT_YEAR=0x%d -DDTINIT_MONTH=0x%d -DDTINIT_DAY=0x%d -DDTINIT_WDAY=0x%d' `date +%-y` `date +%-m` `date +%-d` `date +%-w`)
DT_TIME := $(shell printf ' -DDTINIT_HOUR=0x%d -DDTINIT_MIN=0x%d -DDTINIT_SEC=0x%d' `date +%-H` `date +%-M` `date +%-S`)
DTINIT := $(DT_DATE) $(DT_TIME)
###############################################################################
# Project Configuration #
## The name of the project
TARGET := PowerOS
## The device to compile for
MCU := 16LF19197
## Source directory
SOURCE_DIR := src
## Include directory
INCLUDE_DIR := src
## Build directory
BUILD_DIR := build
################################################################################
# Programmer options #
## Serial port of a device with the flipflop bootloader
PROGRAMMER_PORT := /dev/ttyUSB0
PROGRAMMER_BAUD := 500000
PROGRAMMER_FLAGS := -d $(MCU) -c flipflop -P $(PROGRAMMER_PORT) -B $(PROGRAMMER_BAUD)
PROGRAMMER_FLAGS += --pagesize 1024
################################################################################
# Compiler Setup #
## Microchip's XC8 compiler
CC := xc8-cc
## Target Arch flag
TARGET_ARCH := -mcpu=$(MCU)
## Firmware build options
FWFLAGS = -D_XTAL_FREQ=${XTAL_FREQ} -DPCB_REV=${PCB_REV} -DLOG_LVL=$(LOG_LVL) $(DTINIT)
## Options for the xc8 compiler
CFLAGS := -O2 -c
## Options for xc8 compiler linker
LFLAGS := -O2 -mcodeoffset=${BOOT_OFFSET}
################################################################################
# User Config Override #
# -include config.mk
-include $(MODE_FILE)
################################################################################
# Match n' Making #
# Recursively find all *.c files in our SOURCE_DIR exluding the 'modes' directory
SOURCES := $(shell find $(SOURCE_DIR) -name '*.c' -not -path '$(SOURCE_DIR)/modes/*')
# Add modes to build sources
SOURCES += $(foreach mode,$(MODES),$(SOURCE_DIR)/modes/$(mode).c)
# Mode config file template path
MODE_CONFIG_TEMPLATE := $(SOURCE_DIR)/modes/mode_config_template.h
# Mode config file path
MODE_CONFIG := $(SOURCE_DIR)/modes/mode_config.h
# Generate list of p-code object files from sources
OBJECTS := $(SOURCES:$(SOURCE_DIR)/%.c=$(BUILD_DIR)/%.p1)
# Generate list of dependency files
# DEPENDS := $(SOURCES:%.c=$(BUILD_DIR)/%.d)
# Generate list from actual files in directory to get around a bug introduced in make 4.4
DEPENDS := $(shell find $(BUILD_DIR) -name '*.d')
## Generate list of folders in build directory
# BUILD_FILE_DIRS = $(shell find $(BUILD_DIR) -type d)
# Generate p-code files
$(BUILD_DIR)/%.p1: $(SOURCE_DIR)/%.c Makefile
@mkdir -p $(dir $@)
@echo "Compiling $<"
@$(CC) $(TARGET_ARCH) $(CFLAGS) -I$(INCLUDE_DIR)/ ${FWFLAGS} $< -o $@
## Generate bin files (.hex and .elf)
# Note: This command builds everythings,
# maybe we can find a way to split up the actions.
$(BUILD_DIR)/$(TARGET).hex: $(MODE_CONFIG) $(OBJECTS) Makefile
@mkdir -p $(dir $@)
@echo "Building hexfile..."
@$(CC) $(TARGET_ARCH) $(LFLAGS) $(OBJECTS) -o $@
## Generate mode_config.h file
$(MODE_CONFIG): $(MODE_FILE) $(MODE_CONFIG_TEMPLATE) Makefile
@echo "Generating '$(MODE_CONFIG)'..."
@echo -e -n '' $(foreach mode,$(MODES),$(mode)\\n)
@cat $(MODE_CONFIG_TEMPLATE) | \
sed -e 's/\/\/MODE_INCLUDE/$(foreach mode,$(MODES),#include "modes\/$(mode).h"NEWLINE)/' | \
sed -e 's/\/\/MODE_INDEX/$(foreach mode,$(MODES),$(mode)_index,NEWLINE)/' | \
sed -e 's/\/\/MODE_LIST/$(foreach mode,$(MODES),\&$(mode)_mode,NEWLINE)/' | \
sed -e 's/NEWLINE /\n/g' | \
sed -e 's/NEWLINE//' | \
sed -e 's/mode_config_template/mode_config/' \
> $(MODE_CONFIG)
################################################################################
# Make Commands #
## Commands to use
.PHONY: fw config clean fclean flash upload sync info help
########################
# Build Commands #
## Build firmware with settings defined in Makefile. Equal to a plain 'make'
fw: $(BUILD_DIR)/$(TARGET).hex
# Gen config
config: $(SOURCE_DIR)/modes/mode_config.h
########################
# Clean Commands #
## Clean-up build files.
clean:
@echo "Removing firmware build files..."
${eval BUILD_FILE_DIRS = $(shell find $(BUILD_DIR) -type d)}
@rm -fv $(BUILD_FILE_DIRS:%=%/*.*)
@echo ""
## Clean-up generated files
cclean:
@echo "Removing generated config files..."
@rm -fv $(SOURCE_DIR)/modes/mode_config.h
@echo ""
## Clean-up build directories
fclean: clean cclean
@echo "Removing firmware build directories..."
@rm -rfv $(BUILD_DIR)
@echo ""
###########################
# Flashing Commands #
## Uploads the built hexfile onto a device with flipflop using picchick
upload: fw
@echo "Uploading firmware..."
@picchick \
$(PROGRAMMER_FLAGS) \
--flash \
$(BUILD_DIR)/$(TARGET).hex
## Updates the the time compiled into the firmware to the current time
sync:
@echo "Current time:" $(shell date)
touch src/lib/datetime.c
#######################
# Help Commands #
info:
@echo "Sources:"
@echo $(SOURCES)
@echo "Objects:"
@echo $(OBJECTS)
help:
@echo "'make [fw]' - Build firmware"
@echo "'make config' - Generate modes/mode_config.h header file"
@echo "'make upload' - Upload firmware using picchick, building if neccessary"
@echo "'make sync' - Update time next time firmware is built"
@echo "'make clean' - Remove built firmware files"
@echo "'make fclean' - Remove all files and folders created"
@echo " "
.DEFAULT:
@echo "Error: Unknown command"
@make help
# Include dependency rules
include $(DEPENDS)