[FL-1443, FL-1289] Move assets compilation to separate Makefile. Add scripts folder. Add OTP flashing with DFU. (#531)
* Assets: move assets compilation to separate Makefile. Move all scripts to scripts folder. Add scripts ReadMe. Add precompiled assets. * Split assets.py into separate entities. Option bytes for FL-1289 and checker/setter. * Cli: explicitly initialize variable befor use in api_hal_vcp_rx_with_timeout * Rename ob_check script to ob.
This commit is contained in:
parent
359bbdfe69
commit
8116bfcbab
@ -51,7 +51,7 @@ size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool cli_cmd_interrupt_received(Cli* cli) {
|
bool cli_cmd_interrupt_received(Cli* cli) {
|
||||||
char c;
|
char c = '\0';
|
||||||
api_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 1);
|
api_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 1);
|
||||||
return c == CliSymbolAsciiETX;
|
return c == CliSymbolAsciiETX;
|
||||||
}
|
}
|
||||||
|
11
assets/Makefile
Normal file
11
assets/Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
PROJECT_ROOT = $(abspath $(dir $(abspath $(firstword $(MAKEFILE_LIST))))..)
|
||||||
|
|
||||||
|
include $(PROJECT_ROOT)/assets/assets.mk
|
||||||
|
|
||||||
|
$(ASSETS): $(ASSETS_SOURCES) $(ASSETS_COMPILLER)
|
||||||
|
@echo "\tASSETS\t" $@
|
||||||
|
@$(ASSETS_COMPILLER) icons -s $(ASSETS_SOURCE_DIR) -o $(ASSETS_COMPILED_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "\tCLEAN\t"
|
||||||
|
@$(RM) $(ASSETS)
|
@ -1,3 +1,13 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
- Python3
|
||||||
|
- ImageMagic
|
||||||
|
- Make
|
||||||
|
|
||||||
|
# Compiling
|
||||||
|
|
||||||
|
make all
|
||||||
|
|
||||||
# Asset naming rules
|
# Asset naming rules
|
||||||
|
|
||||||
## Images and Animations
|
## Images and Animations
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
ASSETS_DIR := $(PROJECT_ROOT)/assets
|
ASSETS_DIR := $(PROJECT_ROOT)/assets
|
||||||
ASSETS_COMPILLER := $(ASSETS_DIR)/assets.py
|
ASSETS_COMPILLER := $(PROJECT_ROOT)/scripts/assets.py
|
||||||
ASSETS_OUTPUT_DIR := $(ASSETS_DIR)/output
|
ASSETS_COMPILED_DIR := $(ASSETS_DIR)/compiled
|
||||||
ASSETS_SOURCE_DIR := $(ASSETS_DIR)/icons
|
ASSETS_SOURCE_DIR := $(ASSETS_DIR)/icons
|
||||||
|
|
||||||
ASSETS_SOURCES += $(shell find $(ASSETS_SOURCE_DIR) -type f -iname '*.png' -or -iname 'frame_rate')
|
ASSETS_SOURCES += $(shell find $(ASSETS_SOURCE_DIR) -type f -iname '*.png' -or -iname 'frame_rate')
|
||||||
ASSETS += $(ASSETS_OUTPUT_DIR)/assets_icons.c
|
ASSETS += $(ASSETS_COMPILED_DIR)/assets_icons.c
|
||||||
|
|
||||||
CFLAGS += -I$(ASSETS_OUTPUT_DIR)
|
CFLAGS += -I$(ASSETS_COMPILED_DIR)
|
||||||
C_SOURCES += $(ASSETS_OUTPUT_DIR)/assets_icons.c
|
C_SOURCES += $(ASSETS_COMPILED_DIR)/assets_icons.c
|
||||||
|
617
assets/compiled/assets_icons.c
Normal file
617
assets/compiled/assets_icons.c
Normal file
File diff suppressed because one or more lines are too long
131
assets/compiled/assets_icons.h
Normal file
131
assets/compiled/assets_icons.h
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gui/icon.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
I_SDQuestion_35x43,
|
||||||
|
I_SDError_43x35,
|
||||||
|
I_Health_16x16,
|
||||||
|
I_FaceCharging_29x14,
|
||||||
|
I_BatteryBody_52x28,
|
||||||
|
I_Voltage_16x16,
|
||||||
|
I_Temperature_16x16,
|
||||||
|
I_FaceNopower_29x14,
|
||||||
|
I_FaceNormal_29x14,
|
||||||
|
I_Battery_16x16,
|
||||||
|
I_FaceConfused_29x14,
|
||||||
|
I_PassportBottom_128x17,
|
||||||
|
I_DoorLeft_8x56,
|
||||||
|
I_DoorLocked_10x56,
|
||||||
|
I_DoorRight_8x56,
|
||||||
|
I_DoorLeft_70x55,
|
||||||
|
I_PassportLeft_6x47,
|
||||||
|
I_DoorRight_70x55,
|
||||||
|
I_LockPopup_100x49,
|
||||||
|
I_WalkR2_32x32,
|
||||||
|
I_WalkL2_32x32,
|
||||||
|
I_WalkRB1_32x32,
|
||||||
|
I_Home_painting_17x20,
|
||||||
|
I_WalkLB2_32x32,
|
||||||
|
I_Sofa_40x13,
|
||||||
|
I_WalkLB1_32x32,
|
||||||
|
I_PC_22x29,
|
||||||
|
I_WalkL1_32x32,
|
||||||
|
I_TV_20x20,
|
||||||
|
I_WalkR1_32x32,
|
||||||
|
I_WalkRB2_32x32,
|
||||||
|
I_TV_20x24,
|
||||||
|
I_dir_10px,
|
||||||
|
I_Nfc_10px,
|
||||||
|
I_sub1_10px,
|
||||||
|
I_ir_10px,
|
||||||
|
I_ibutt_10px,
|
||||||
|
I_unknown_10px,
|
||||||
|
I_ble_10px,
|
||||||
|
I_125_10px,
|
||||||
|
I_FX_SittingB_40x27,
|
||||||
|
I_BigGames_24x24,
|
||||||
|
I_BigProfile_24x24,
|
||||||
|
I_DolphinOkay_41x43,
|
||||||
|
I_DolphinFirstStart5_45x53,
|
||||||
|
I_DolphinFirstStart4_67x53,
|
||||||
|
I_DolphinFirstStart2_59x51,
|
||||||
|
I_DolphinFirstStart0_70x53,
|
||||||
|
I_DolphinFirstStart6_58x54,
|
||||||
|
I_DolphinFirstStart1_59x53,
|
||||||
|
I_DolphinFirstStart8_56x51,
|
||||||
|
I_DolphinFirstStart7_61x51,
|
||||||
|
I_Flipper_young_80x60,
|
||||||
|
I_BigBurger_24x24,
|
||||||
|
I_FX_Bang_32x6,
|
||||||
|
I_DolphinFirstStart3_57x48,
|
||||||
|
I_BadUsb_9x8,
|
||||||
|
I_PlaceholderR_30x13,
|
||||||
|
I_Background_128x8,
|
||||||
|
I_Lock_8x8,
|
||||||
|
I_Battery_26x8,
|
||||||
|
I_PlaceholderL_11x13,
|
||||||
|
I_Battery_19x8,
|
||||||
|
I_SDcardMounted_11x8,
|
||||||
|
I_SDcardFail_11x8,
|
||||||
|
I_USBConnected_15x8,
|
||||||
|
I_Bluetooth_5x8,
|
||||||
|
I_Background_128x11,
|
||||||
|
I_IrdaArrowUp_4x8,
|
||||||
|
I_IrdaLearnShort_128x31,
|
||||||
|
I_IrdaArrowDown_4x8,
|
||||||
|
I_IrdaLearn_128x64,
|
||||||
|
I_IrdaSend_128x64,
|
||||||
|
I_IrdaSendShort_128x34,
|
||||||
|
I_passport_happy1_43x45,
|
||||||
|
I_passport_bad3_43x45,
|
||||||
|
I_passport_okay2_43x45,
|
||||||
|
I_passport_bad2_43x45,
|
||||||
|
I_passport_okay3_43x45,
|
||||||
|
I_passport_bad1_43x45,
|
||||||
|
I_passport_happy3_43x45,
|
||||||
|
I_passport_happy2_43x45,
|
||||||
|
I_passport_okay1_43x45,
|
||||||
|
I_ButtonRightSmall_3x5,
|
||||||
|
I_ButtonLeft_4x7,
|
||||||
|
I_ButtonLeftSmall_3x5,
|
||||||
|
I_ButtonRight_4x7,
|
||||||
|
I_ButtonCenter_7x7,
|
||||||
|
A_Games_14,
|
||||||
|
A_Plugins_14,
|
||||||
|
A_Passport_14,
|
||||||
|
A_Sub1ghz_14,
|
||||||
|
A_NFC_14,
|
||||||
|
A_Tamagotchi_14,
|
||||||
|
A_FileManager_14,
|
||||||
|
A_125khz_14,
|
||||||
|
A_U2F_14,
|
||||||
|
A_Infrared_14,
|
||||||
|
A_Power_14,
|
||||||
|
A_Settings_14,
|
||||||
|
A_iButton_14,
|
||||||
|
A_Bluetooth_14,
|
||||||
|
A_GPIO_14,
|
||||||
|
I_DolphinMafia_115x62,
|
||||||
|
I_DolphinExcited_64x63,
|
||||||
|
I_iButtonDolphinSuccess_109x60,
|
||||||
|
I_iButtonDolphinVerySuccess_108x52,
|
||||||
|
I_iButtonKey_49x44,
|
||||||
|
I_DolphinNice_96x59,
|
||||||
|
I_DolphinWait_61x59,
|
||||||
|
A_Wink_128x64,
|
||||||
|
A_MDWL_32x32,
|
||||||
|
A_MDWR_32x32,
|
||||||
|
A_WatchingTV_128x64,
|
||||||
|
A_MDI_32x32,
|
||||||
|
A_MDWRB_32x32,
|
||||||
|
A_MDIB_32x32,
|
||||||
|
A_FX_Sitting_40x27,
|
||||||
|
A_MDWLB_32x32,
|
||||||
|
I_KeySave_24x11,
|
||||||
|
I_KeyBackspaceSelected_16x9,
|
||||||
|
I_KeySaveSelected_24x11,
|
||||||
|
I_KeyBackspace_16x9,
|
||||||
|
} IconName;
|
||||||
|
|
||||||
|
Icon * assets_icons_get(IconName name);
|
5
assets/compiled/assets_icons_i.h
Normal file
5
assets/compiled/assets_icons_i.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assets_icons.h>
|
||||||
|
|
||||||
|
const IconData * assets_icons_get_data(IconName name);
|
1
assets/output/.gitignore
vendored
1
assets/output/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
*
|
|
@ -8,7 +8,7 @@ ASM_SOURCES += $(wildcard src/*.s)
|
|||||||
C_SOURCES += $(wildcard src/*.c)
|
C_SOURCES += $(wildcard src/*.c)
|
||||||
CPP_SOURCES += $(wildcard src/*.cpp)
|
CPP_SOURCES += $(wildcard src/*.cpp)
|
||||||
|
|
||||||
TARGET ?= f5
|
TARGET ?= f6
|
||||||
TARGET_DIR = targets/$(TARGET)
|
TARGET_DIR = targets/$(TARGET)
|
||||||
include $(TARGET_DIR)/target.mk
|
include $(TARGET_DIR)/target.mk
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ PROJECT = firmware
|
|||||||
|
|
||||||
include $(PROJECT_ROOT)/make/base.mk
|
include $(PROJECT_ROOT)/make/base.mk
|
||||||
include $(PROJECT_ROOT)/assets/assets.mk
|
include $(PROJECT_ROOT)/assets/assets.mk
|
||||||
|
CFLAGS += -I$(ASSETS_COMPILED_DIR)
|
||||||
include $(PROJECT_ROOT)/core/core.mk
|
include $(PROJECT_ROOT)/core/core.mk
|
||||||
include $(PROJECT_ROOT)/applications/applications.mk
|
include $(PROJECT_ROOT)/applications/applications.mk
|
||||||
include $(PROJECT_ROOT)/lib/lib.mk
|
include $(PROJECT_ROOT)/lib/lib.mk
|
||||||
@ -10,7 +11,7 @@ include $(PROJECT_ROOT)/lib/lib.mk
|
|||||||
CFLAGS += -Werror -Wno-address-of-packed-member
|
CFLAGS += -Werror -Wno-address-of-packed-member
|
||||||
CPPFLAGS += -Werror
|
CPPFLAGS += -Werror
|
||||||
|
|
||||||
TARGET ?= f5
|
TARGET ?= f6
|
||||||
|
|
||||||
TARGET_DIR = targets/$(TARGET)
|
TARGET_DIR = targets/$(TARGET)
|
||||||
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -x -e
|
|
||||||
|
|
||||||
rm bootloader/.obj/f*/flash || true
|
|
||||||
make -C bootloader -j9 flash
|
|
||||||
|
|
||||||
rm firmware/.obj/f*/flash || true
|
|
||||||
make -C firmware -j9 flash
|
|
@ -47,15 +47,15 @@ $(OBJ_DIR)/$(PROJECT).bin: $(OBJ_DIR)/$(PROJECT).elf
|
|||||||
@echo "\tBIN\t" $@
|
@echo "\tBIN\t" $@
|
||||||
@$(BIN) $< $@
|
@$(BIN) $< $@
|
||||||
|
|
||||||
$(OBJ_DIR)/%.o: %.c $(OBJ_DIR)/BUILD_FLAGS $(ASSETS)
|
$(OBJ_DIR)/%.o: %.c $(OBJ_DIR)/BUILD_FLAGS
|
||||||
@echo "\tCC\t" $< "->" $@
|
@echo "\tCC\t" $< "->" $@
|
||||||
@$(CC) $(CFLAGS) -c $< -o $@
|
@$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJ_DIR)/%.o: %.s $(OBJ_DIR)/BUILD_FLAGS $(ASSETS)
|
$(OBJ_DIR)/%.o: %.s $(OBJ_DIR)/BUILD_FLAGS
|
||||||
@echo "\tASM\t" $< "->" $@
|
@echo "\tASM\t" $< "->" $@
|
||||||
@$(AS) $(CFLAGS) -c $< -o $@
|
@$(AS) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJ_DIR)/%.o: %.cpp $(OBJ_DIR)/BUILD_FLAGS $(ASSETS)
|
$(OBJ_DIR)/%.o: %.cpp $(OBJ_DIR)/BUILD_FLAGS
|
||||||
@echo "\tCPP\t" $< "->" $@
|
@echo "\tCPP\t" $< "->" $@
|
||||||
@$(CPP) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
@$(CPP) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
@ -67,10 +67,6 @@ $(OBJ_DIR)/upload: $(OBJ_DIR)/$(PROJECT).bin
|
|||||||
dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS)
|
dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS)
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(ASSETS): $(ASSETS_SOURCES) $(ASSETS_COMPILLER)
|
|
||||||
@echo "\tASSETS\t" $@
|
|
||||||
@$(ASSETS_COMPILLER) icons -s $(ASSETS_SOURCE_DIR) -o $(ASSETS_OUTPUT_DIR)
|
|
||||||
|
|
||||||
flash: $(OBJ_DIR)/flash
|
flash: $(OBJ_DIR)/flash
|
||||||
|
|
||||||
upload: $(OBJ_DIR)/upload
|
upload: $(OBJ_DIR)/upload
|
||||||
@ -104,7 +100,6 @@ bm_debug: flash
|
|||||||
clean:
|
clean:
|
||||||
@echo "\tCLEAN\t"
|
@echo "\tCLEAN\t"
|
||||||
@$(RM) $(OBJ_DIR)/*
|
@$(RM) $(OBJ_DIR)/*
|
||||||
@$(RM) $(ASSETS)
|
|
||||||
|
|
||||||
z: clean
|
z: clean
|
||||||
$(MAKE) all
|
$(MAKE) all
|
||||||
@ -123,7 +118,7 @@ format:
|
|||||||
@echo "Formatting sources with clang-format"
|
@echo "Formatting sources with clang-format"
|
||||||
@clang-format -style=file -i $(FORMAT_SOURCES)
|
@clang-format -style=file -i $(FORMAT_SOURCES)
|
||||||
|
|
||||||
generate_cscope_db: $(ASSETS)
|
generate_cscope_db:
|
||||||
@echo "$(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/source.list.p
|
@echo "$(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES)" | tr ' ' '\n' > $(OBJ_DIR)/source.list.p
|
||||||
@cat ~/headers.list >> $(OBJ_DIR)/source.list.p
|
@cat ~/headers.list >> $(OBJ_DIR)/source.list.p
|
||||||
@cat $(OBJ_DIR)/source.list.p | sed -e "s|^[^//]|$$PWD/&|g" > $(OBJ_DIR)/source.list
|
@cat $(OBJ_DIR)/source.list.p | sed -e "s|^[^//]|$$PWD/&|g" > $(OBJ_DIR)/source.list
|
||||||
|
51
scripts/ReadMe.md
Normal file
51
scripts/ReadMe.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
This folder contains differnt scripts that automates routine actions.
|
||||||
|
Flashing scripts are based on cli version of [STM32CubeProgrammer](https://www.st.com/en/development-tools/stm32cubeprog.html).
|
||||||
|
You will need to add STM32_Programmer_CLI to your path to use them.
|
||||||
|
|
||||||
|
# Flashing empty MCU/Flipper
|
||||||
|
|
||||||
|
Always flash your device in the folllowing sequence:
|
||||||
|
|
||||||
|
- OTP (Only on empty MCU)
|
||||||
|
- Core2 firmware
|
||||||
|
- Core1 firmware
|
||||||
|
- Option Bytes
|
||||||
|
|
||||||
|
## Otp flashing
|
||||||
|
|
||||||
|
!!! Flashing incorrect OTP may permanently brick your device !!!
|
||||||
|
|
||||||
|
Normally OTP data generated and flashed at factory.
|
||||||
|
In case if MCU was replaced you'll need correct OTP data to be able to use companion applications.
|
||||||
|
Use `otp.py` to generate OTP data and `flash_otp_version_*` to flash OTP zone.
|
||||||
|
You will need exact main board revision to genrate OTP data. It can be found on main PCB.
|
||||||
|
|
||||||
|
!!! Flashing incorrect OTP may permanently brick your device !!!
|
||||||
|
|
||||||
|
## Core2 flashing
|
||||||
|
|
||||||
|
Script blindly updates FUS and Radiostack. This operation is going to corrupt bootloader and firmware.
|
||||||
|
Reflash Core1 after Core2.
|
||||||
|
|
||||||
|
## Core1 flashing
|
||||||
|
|
||||||
|
Script compiles and flashes both bootloader and firmware.
|
||||||
|
|
||||||
|
## Option Bytes
|
||||||
|
|
||||||
|
!!! Setting incorrect Otion Bytes may brick your MCU !!!
|
||||||
|
|
||||||
|
Defaults are mostly OK, but there are couple things that we'd like to tune.
|
||||||
|
Also OB may be damaged, so we've made couple scripts to check and set option bytes.
|
||||||
|
|
||||||
|
!!! Setting incorrect Otion Bytes may brick your MCU !!!
|
||||||
|
|
||||||
|
Checking option bytes:
|
||||||
|
|
||||||
|
ob.py check
|
||||||
|
|
||||||
|
Setting option bytes:
|
||||||
|
|
||||||
|
ob.py set
|
@ -6,9 +6,6 @@ import subprocess
|
|||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
|
||||||
import struct
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
ICONS_SUPPORTED_FORMATS = ["png"]
|
ICONS_SUPPORTED_FORMATS = ["png"]
|
||||||
|
|
||||||
@ -51,7 +48,7 @@ Icon * assets_icons_get(IconName name) {
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Assets:
|
class Main:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# command args
|
# command args
|
||||||
self.parser = argparse.ArgumentParser()
|
self.parser = argparse.ArgumentParser()
|
||||||
@ -67,22 +64,6 @@ class Assets:
|
|||||||
"-o", "--output-directory", help="Output directory"
|
"-o", "--output-directory", help="Output directory"
|
||||||
)
|
)
|
||||||
self.parser_icons.set_defaults(func=self.icons)
|
self.parser_icons.set_defaults(func=self.icons)
|
||||||
self.parser_otp = self.subparsers.add_parser(
|
|
||||||
"otp", help="OTP HW version generator"
|
|
||||||
)
|
|
||||||
self.parser_otp.add_argument(
|
|
||||||
"--version", type=int, help="Version", required=True
|
|
||||||
)
|
|
||||||
self.parser_otp.add_argument(
|
|
||||||
"--firmware", type=int, help="Firmware", required=True
|
|
||||||
)
|
|
||||||
self.parser_otp.add_argument("--body", type=int, help="Body", required=True)
|
|
||||||
self.parser_otp.add_argument(
|
|
||||||
"--connect", type=int, help="Connect", required=True
|
|
||||||
)
|
|
||||||
self.parser_otp.add_argument("--name", type=str, help="Name", required=True)
|
|
||||||
self.parser_otp.add_argument("file", help="Output file")
|
|
||||||
self.parser_otp.set_defaults(func=self.otp)
|
|
||||||
# logging
|
# logging
|
||||||
self.logger = logging.getLogger()
|
self.logger = logging.getLogger()
|
||||||
|
|
||||||
@ -101,39 +82,6 @@ class Assets:
|
|||||||
# execute requested function
|
# execute requested function
|
||||||
self.args.func()
|
self.args.func()
|
||||||
|
|
||||||
def otp(self):
|
|
||||||
self.logger.debug(f"Generating OTP")
|
|
||||||
|
|
||||||
if self.args.name:
|
|
||||||
name = re.sub(
|
|
||||||
"[^a-zA-Z0-9.]", "", self.args.name
|
|
||||||
) # Filter all special characters
|
|
||||||
name = list(
|
|
||||||
map(str, map(ord, name[0:8]))
|
|
||||||
) # Strip to 8 chars and map to ascii codes
|
|
||||||
while len(name) < 8:
|
|
||||||
name.append("0")
|
|
||||||
|
|
||||||
n1, n2, n3, n4, n5, n6, n7, n8 = map(int, name)
|
|
||||||
|
|
||||||
data = struct.pack(
|
|
||||||
"<BBBBLBBBBBBBB",
|
|
||||||
self.args.version,
|
|
||||||
self.args.firmware,
|
|
||||||
self.args.body,
|
|
||||||
self.args.connect,
|
|
||||||
int(datetime.datetime.now().timestamp()),
|
|
||||||
n1,
|
|
||||||
n2,
|
|
||||||
n3,
|
|
||||||
n4,
|
|
||||||
n5,
|
|
||||||
n6,
|
|
||||||
n7,
|
|
||||||
n8,
|
|
||||||
)
|
|
||||||
open(self.args.file, "wb").write(data)
|
|
||||||
|
|
||||||
def icons(self):
|
def icons(self):
|
||||||
self.logger.debug(f"Converting icons")
|
self.logger.debug(f"Converting icons")
|
||||||
icons_c = open(os.path.join(self.args.output_directory, "assets_icons.c"), "w")
|
icons_c = open(os.path.join(self.args.output_directory, "assets_icons.c"), "w")
|
||||||
@ -248,4 +196,4 @@ class Assets:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
Assets()()
|
Main()()
|
12
scripts/flash_core1_main_swd.sh
Executable file
12
scripts/flash_core1_main_swd.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -x -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||||
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
rm $PROJECT_DIR/bootloader/.obj/f*/flash || true
|
||||||
|
make -C $PROJECT_DIR/bootloader -j9 flash
|
||||||
|
|
||||||
|
rm $PROJECT_DIR/firmware/.obj/f*/flash || true
|
||||||
|
make -C $PROJECT_DIR/firmware -j9 flash
|
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
set -x -e
|
set -x -e
|
||||||
|
|
||||||
COPRO_DIR="lib/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x"
|
SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||||
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||||
|
COPRO_DIR="$PROJECT_DIR/lib/STM32CubeWB/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x"
|
||||||
|
|
||||||
STM32_Programmer_CLI -c port=swd -fwupgrade $COPRO_DIR/stm32wb5x_FUS_fw_1_0_2.bin 0x080EC000 || true
|
STM32_Programmer_CLI -c port=swd -fwupgrade $COPRO_DIR/stm32wb5x_FUS_fw_1_0_2.bin 0x080EC000 || true
|
||||||
STM32_Programmer_CLI -c port=swd
|
STM32_Programmer_CLI -c port=swd
|
17
scripts/flash_otp_version_dfu.sh
Executable file
17
scripts/flash_otp_version_dfu.sh
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -x -e
|
||||||
|
|
||||||
|
if [ "$#" -ne 1 ]; then
|
||||||
|
echo "OTP file required"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f $1 ]; then
|
||||||
|
echo "Unable to open OTP file"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
STM32_Programmer_CLI -c port=usb1 -d $1 0x1FFF7000
|
||||||
|
|
||||||
|
STM32_Programmer_CLI -c port=usb1 -r8 0x1FFF7000 8
|
113
scripts/ob.py
Executable file
113
scripts/ob.py
Executable file
@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Main:
|
||||||
|
def __init__(self):
|
||||||
|
# command args
|
||||||
|
self.parser = argparse.ArgumentParser()
|
||||||
|
self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
|
||||||
|
self.subparsers = self.parser.add_subparsers(help="sub-command help")
|
||||||
|
self.parser_check = self.subparsers.add_parser(
|
||||||
|
"check", help="Check Option Bytes"
|
||||||
|
)
|
||||||
|
self.parser_check.set_defaults(func=self.check)
|
||||||
|
self.parser_set = self.subparsers.add_parser("set", help="Set Option Bytes")
|
||||||
|
self.parser_set.set_defaults(func=self.set)
|
||||||
|
# logging
|
||||||
|
self.logger = logging.getLogger()
|
||||||
|
# OB
|
||||||
|
self.ob = {}
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
self.args = self.parser.parse_args()
|
||||||
|
if "func" not in self.args:
|
||||||
|
self.parser.error("Choose something to do")
|
||||||
|
# configure log output
|
||||||
|
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
|
||||||
|
self.logger.setLevel(self.log_level)
|
||||||
|
self.handler = logging.StreamHandler(sys.stdout)
|
||||||
|
self.handler.setLevel(self.log_level)
|
||||||
|
self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
|
||||||
|
self.handler.setFormatter(self.formatter)
|
||||||
|
self.logger.addHandler(self.handler)
|
||||||
|
# execute requested function
|
||||||
|
self.loadOB()
|
||||||
|
self.args.func()
|
||||||
|
|
||||||
|
def loadOB(self):
|
||||||
|
self.logger.info(f"Loading Option Bytes data")
|
||||||
|
file_path = os.path.join(os.path.dirname(sys.argv[0]), "ob.data")
|
||||||
|
file = open(file_path, "r")
|
||||||
|
for line in file.readlines():
|
||||||
|
k, v, o = line.split(":")
|
||||||
|
self.ob[k.strip()] = v.strip(), o.strip()
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
self.logger.info(f"Checking Option Bytes")
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(
|
||||||
|
["STM32_Programmer_CLI", "-q", "-c port=swd", "-ob displ"]
|
||||||
|
)
|
||||||
|
assert output
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Failed to call STM32_Programmer_CLI")
|
||||||
|
self.logger.exception(e)
|
||||||
|
return
|
||||||
|
ob_correct = True
|
||||||
|
for line in output.decode().split("\n"):
|
||||||
|
line = line.strip()
|
||||||
|
if not ":" in line:
|
||||||
|
self.logger.debug(f"Skipping line: {line}")
|
||||||
|
continue
|
||||||
|
key, data = line.split(":", 1)
|
||||||
|
key = key.strip()
|
||||||
|
data = data.strip()
|
||||||
|
if not key in self.ob.keys():
|
||||||
|
self.logger.debug(f"Skipping key: {key}")
|
||||||
|
continue
|
||||||
|
self.logger.debug(f"Processing key: {key} {data}")
|
||||||
|
value, comment = data.split(" ", 1)
|
||||||
|
value = value.strip()
|
||||||
|
comment = comment.strip()
|
||||||
|
if self.ob[key][0] != value:
|
||||||
|
self.logger.error(
|
||||||
|
f"Invalid OB: {key} {value}, expected: {self.ob[key][0]}"
|
||||||
|
)
|
||||||
|
ob_correct = False
|
||||||
|
if ob_correct:
|
||||||
|
self.logger.info(f"OB Check OK")
|
||||||
|
else:
|
||||||
|
self.logger.error(f"OB Check FAIL")
|
||||||
|
exit(255)
|
||||||
|
|
||||||
|
def set(self):
|
||||||
|
self.logger.info(f"Setting Option Bytes")
|
||||||
|
options = []
|
||||||
|
for key, (value, attr) in self.ob.items():
|
||||||
|
if "w" in attr:
|
||||||
|
options.append(f"{key}={value}")
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(
|
||||||
|
[
|
||||||
|
"STM32_Programmer_CLI",
|
||||||
|
"-q",
|
||||||
|
"-c port=swd",
|
||||||
|
f"-ob {' '.join(options)}",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert output
|
||||||
|
self.logger.info(f"Success")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Failed to call STM32_Programmer_CLI")
|
||||||
|
self.logger.exception(e)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Main()()
|
34
scripts/ob_check.data
Normal file
34
scripts/ob_check.data
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
RDP:0xAA:r
|
||||||
|
BOR_LEV:0x4:rw
|
||||||
|
nBOOT0:0x1:rw
|
||||||
|
nBOOT1:0x1:rw
|
||||||
|
nSWBOOT0:0x1:rw
|
||||||
|
SRAM2RST:0x0:rw
|
||||||
|
SRAM2PE:0x1:rw
|
||||||
|
nRST_STOP:0x1:rw
|
||||||
|
nRST_STDBY:0x1:rw
|
||||||
|
nRSTSHDW:0x1:rw
|
||||||
|
WWDGSW:0x1:rw
|
||||||
|
IWGDSTDBY:0x1:rw
|
||||||
|
IWDGSTOP:0x1:rw
|
||||||
|
IWDGSW:0x1:rw
|
||||||
|
IPCCDBA:0x0:rw
|
||||||
|
ESE:0x1:r
|
||||||
|
SFSA:0xCB:r
|
||||||
|
FSD:0x0:r
|
||||||
|
DDS:0x1:r
|
||||||
|
C2OPT:0x1:r
|
||||||
|
NBRSD:0x0:r
|
||||||
|
SNBRSA:0xF:r
|
||||||
|
BRSD:0x0:r
|
||||||
|
SBRSA:0xA:r
|
||||||
|
SBRV:0x32C00:r
|
||||||
|
PCROP1A_STRT:0x1FF:r
|
||||||
|
PCROP1A_END:0x0:r
|
||||||
|
PCROP_RDP:0x1:r
|
||||||
|
PCROP1B_STRT:0x1FF:r
|
||||||
|
PCROP1B_END:0x0:r
|
||||||
|
WRP1A_STRT:0xFF:r
|
||||||
|
WRP1A_END:0x0:r
|
||||||
|
WRP1B_STRT:0xFF:r
|
||||||
|
WRP1B_END:0x0:r
|
91
scripts/otp.py
Executable file
91
scripts/otp.py
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import struct
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class Main:
|
||||||
|
def __init__(self):
|
||||||
|
# command args
|
||||||
|
self.parser = argparse.ArgumentParser()
|
||||||
|
self.parser.add_argument("-d", "--debug", action="store_true", help="Debug")
|
||||||
|
self.subparsers = self.parser.add_subparsers(help="sub-command help")
|
||||||
|
self.parser_generate = self.subparsers.add_parser(
|
||||||
|
"generate", help="OTP HW version generator"
|
||||||
|
)
|
||||||
|
self.parser_generate.add_argument(
|
||||||
|
"--version", type=int, help="Version", required=True
|
||||||
|
)
|
||||||
|
self.parser_generate.add_argument(
|
||||||
|
"--firmware", type=int, help="Firmware", required=True
|
||||||
|
)
|
||||||
|
self.parser_generate.add_argument(
|
||||||
|
"--body", type=int, help="Body", required=True
|
||||||
|
)
|
||||||
|
self.parser_generate.add_argument(
|
||||||
|
"--connect", type=int, help="Connect", required=True
|
||||||
|
)
|
||||||
|
self.parser_generate.add_argument(
|
||||||
|
"--name", type=str, help="Name", required=True
|
||||||
|
)
|
||||||
|
self.parser_generate.add_argument("file", help="Output file")
|
||||||
|
self.parser_generate.set_defaults(func=self.generate)
|
||||||
|
# logging
|
||||||
|
self.logger = logging.getLogger()
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
self.args = self.parser.parse_args()
|
||||||
|
if "func" not in self.args:
|
||||||
|
self.parser.error("Choose something to do")
|
||||||
|
# configure log output
|
||||||
|
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
|
||||||
|
self.logger.setLevel(self.log_level)
|
||||||
|
self.handler = logging.StreamHandler(sys.stdout)
|
||||||
|
self.handler.setLevel(self.log_level)
|
||||||
|
self.formatter = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s")
|
||||||
|
self.handler.setFormatter(self.formatter)
|
||||||
|
self.logger.addHandler(self.handler)
|
||||||
|
# execute requested function
|
||||||
|
self.args.func()
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
self.logger.debug(f"Generating OTP")
|
||||||
|
|
||||||
|
if self.args.name:
|
||||||
|
name = re.sub(
|
||||||
|
"[^a-zA-Z0-9.]", "", self.args.name
|
||||||
|
) # Filter all special characters
|
||||||
|
name = list(
|
||||||
|
map(str, map(ord, name[0:8]))
|
||||||
|
) # Strip to 8 chars and map to ascii codes
|
||||||
|
while len(name) < 8:
|
||||||
|
name.append("0")
|
||||||
|
|
||||||
|
n1, n2, n3, n4, n5, n6, n7, n8 = map(int, name)
|
||||||
|
|
||||||
|
data = struct.pack(
|
||||||
|
"<BBBBLBBBBBBBB",
|
||||||
|
self.args.version,
|
||||||
|
self.args.firmware,
|
||||||
|
self.args.body,
|
||||||
|
self.args.connect,
|
||||||
|
int(datetime.datetime.now().timestamp()),
|
||||||
|
n1,
|
||||||
|
n2,
|
||||||
|
n3,
|
||||||
|
n4,
|
||||||
|
n5,
|
||||||
|
n6,
|
||||||
|
n7,
|
||||||
|
n8,
|
||||||
|
)
|
||||||
|
open(self.args.file, "wb").write(data)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Main()()
|
@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
echo "RUN SYNTAX CHECK INSIDE CONTAINER"
|
|
||||||
docker-compose exec dev ./docker/syntax_check.sh
|
|
Loading…
Reference in New Issue
Block a user