diff --git a/latest/Firmware/Bootloader/.cproject b/latest/Firmware/Bootloader/.cproject
index 5d229d8..30259b0 100644
--- a/latest/Firmware/Bootloader/.cproject
+++ b/latest/Firmware/Bootloader/.cproject
@@ -607,7 +607,7 @@
-
+
@@ -619,7 +619,7 @@
-
+
diff --git a/latest/Firmware/Bootloader/.gitignore b/latest/Firmware/Bootloader/.gitignore
index 4ff6d4a..cb73b08 100644
--- a/latest/Firmware/Bootloader/.gitignore
+++ b/latest/Firmware/Bootloader/.gitignore
@@ -9,4 +9,4 @@
/L422
/L431
/L432
-
+/L412_Shrunk/
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk b/latest/Firmware/Bootloader/L412 (Shrunk)/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
deleted file mode 100644
index 3d4ba8c..0000000
--- a/latest/Firmware/Bootloader/L412 (Shrunk)/Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
+++ /dev/null
@@ -1,93 +0,0 @@
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c \
-../Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c
-
-OBJS += \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.o \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.o
-
-C_DEPS += \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_crc_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.d \
-./Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-Drivers/STM32L4xx_HAL_Driver/Src/%.o: ../Drivers/STM32L4xx_HAL_Driver/Src/%.c Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
- @echo 'Building file: $<'
- @echo 'Invoking: GNU ARM Cross C Compiler'
- arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -flto -Wall -DSTM32L412xx -D__SHRINK_TO_64K__=1 -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Inc" -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Drivers/STM32L4xx_HAL_Driver/Inc" -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Drivers/CMSIS/Include" -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Drivers/CMSIS/Device/ST/STM32L4xx/Include" -std=gnu11 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/Src/subdir.mk b/latest/Firmware/Bootloader/L412 (Shrunk)/Src/subdir.mk
deleted file mode 100644
index 006dc97..0000000
--- a/latest/Firmware/Bootloader/L412 (Shrunk)/Src/subdir.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../Src/crc32.c \
-../Src/fw_update.c \
-../Src/main.c \
-../Src/printf2.c \
-../Src/stm32l4xx_hal_msp.c \
-../Src/stm32l4xx_it.c \
-../Src/system_stm32l4xx.c
-
-OBJS += \
-./Src/crc32.o \
-./Src/fw_update.o \
-./Src/main.o \
-./Src/printf2.o \
-./Src/stm32l4xx_hal_msp.o \
-./Src/stm32l4xx_it.o \
-./Src/system_stm32l4xx.o
-
-C_DEPS += \
-./Src/crc32.d \
-./Src/fw_update.d \
-./Src/main.d \
-./Src/printf2.d \
-./Src/stm32l4xx_hal_msp.d \
-./Src/stm32l4xx_it.d \
-./Src/system_stm32l4xx.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-Src/%.o: ../Src/%.c Src/subdir.mk
- @echo 'Building file: $<'
- @echo 'Invoking: GNU ARM Cross C Compiler'
- arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -flto -Wall -DSTM32L412xx -D__SHRINK_TO_64K__=1 -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Inc" -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Drivers/STM32L4xx_HAL_Driver/Inc" -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Drivers/CMSIS/Include" -I"/Users/peter/github/maiana/latest/Firmware/Bootloader/Drivers/CMSIS/Device/ST/STM32L4xx/Include" -std=gnu11 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/maiana-bootloader.bin b/latest/Firmware/Bootloader/L412 (Shrunk)/maiana-bootloader.bin
deleted file mode 100755
index 802d6a1..0000000
Binary files a/latest/Firmware/Bootloader/L412 (Shrunk)/maiana-bootloader.bin and /dev/null differ
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/makefile b/latest/Firmware/Bootloader/L412 (Shrunk)/makefile
deleted file mode 100644
index 539de97..0000000
--- a/latest/Firmware/Bootloader/L412 (Shrunk)/makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
--include ../makefile.init
-
-RM := rm -rf
-
-# All of the sources participating in the build are defined here
--include sources.mk
--include startup/subdir.mk
--include Src/subdir.mk
--include Drivers/STM32L4xx_HAL_Driver/Src/subdir.mk
--include subdir.mk
--include objects.mk
-
-ifneq ($(MAKECMDGOALS),clean)
-ifneq ($(strip $(ASM_DEPS)),)
--include $(ASM_DEPS)
-endif
-ifneq ($(strip $(S_UPPER_DEPS)),)
--include $(S_UPPER_DEPS)
-endif
-ifneq ($(strip $(C_DEPS)),)
--include $(C_DEPS)
-endif
-endif
-
--include ../makefile.defs
-
-OPTIONAL_TOOL_DEPS := \
-$(wildcard ../makefile.defs) \
-$(wildcard ../makefile.init) \
-$(wildcard ../makefile.targets) \
-
-
-BUILD_ARTIFACT_NAME := maiana-bootloader
-BUILD_ARTIFACT_EXTENSION := elf
-BUILD_ARTIFACT_PREFIX :=
-BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ARTIFACT_EXTENSION),.$(BUILD_ARTIFACT_EXTENSION),)
-
-# Add inputs and outputs from these tool invocations to the build variables
-SECONDARY_FLASH += \
-maiana-bootloader.bin \
-
-SECONDARY_SIZE += \
-maiana-bootloader.siz \
-
-
-# All Target
-all:
- +@$(MAKE) --no-print-directory main-build && $(MAKE) --no-print-directory post-build
-
-# Main-build Target
-main-build: maiana-bootloader.elf
-
-# Tool invocations
-maiana-bootloader.elf: $(OBJS) $(USER_OBJS) makefile objects.mk $(OPTIONAL_TOOL_DEPS)
- @echo 'Building target: $@'
- @echo 'Invoking: GNU ARM Cross C Linker'
- arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -flto -Wall -T "/Users/peter/github/maiana/latest/Firmware/Bootloader/STM32L4xx_FLASH.ld" -Xlinker --gc-sections -s -Wl,-Map,"maiana-bootloader.map" --specs=nano.specs --specs=nosys.specs --specs=rdimon.specs -o "maiana-bootloader.elf" $(OBJS) $(USER_OBJS) $(LIBS)
- @echo 'Finished building target: $@'
- @echo ' '
-
-maiana-bootloader.bin: maiana-bootloader.elf makefile objects.mk $(OPTIONAL_TOOL_DEPS)
- @echo 'Invoking: GNU ARM Cross Create Flash Image'
- arm-none-eabi-objcopy -O binary "maiana-bootloader.elf" "maiana-bootloader.bin"
- @echo 'Finished building: $@'
- @echo ' '
-
-maiana-bootloader.siz: maiana-bootloader.elf makefile objects.mk $(OPTIONAL_TOOL_DEPS)
- @echo 'Invoking: GNU ARM Cross Print Size'
- arm-none-eabi-size --format=sysv "maiana-bootloader.elf"
- @echo 'Finished building: $@'
- @echo ' '
-
-# Other Targets
-clean:
- -$(RM) $(OBJS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS) maiana-bootloader.elf
- -@echo ' '
-
-post-build:
- -@echo 'Generating binary and Printing size information:'
- -arm-none-eabi-objcopy -O binary "maiana-bootloader.elf" "maiana-bootloader.bin" && arm-none-eabi-size "maiana-bootloader.elf"
- -@echo ' '
-
-.PHONY: all clean dependents main-build post-build
-
--include ../makefile.targets
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/objects.mk b/latest/Firmware/Bootloader/L412 (Shrunk)/objects.mk
deleted file mode 100644
index 742c2da..0000000
--- a/latest/Firmware/Bootloader/L412 (Shrunk)/objects.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-USER_OBJS :=
-
-LIBS :=
-
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/sources.mk b/latest/Firmware/Bootloader/L412 (Shrunk)/sources.mk
deleted file mode 100644
index b004b8f..0000000
--- a/latest/Firmware/Bootloader/L412 (Shrunk)/sources.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-ELF_SRCS :=
-OBJ_SRCS :=
-ASM_SRCS :=
-C_SRCS :=
-S_UPPER_SRCS :=
-O_SRCS :=
-OBJS :=
-SECONDARY_FLASH :=
-SECONDARY_SIZE :=
-ASM_DEPS :=
-S_UPPER_DEPS :=
-C_DEPS :=
-
-# Every subdirectory with source files must be described here
-SUBDIRS := \
-Drivers/STM32L4xx_HAL_Driver/Src \
-Src \
-startup \
-
diff --git a/latest/Firmware/Bootloader/L412 (Shrunk)/startup/subdir.mk b/latest/Firmware/Bootloader/L412 (Shrunk)/startup/subdir.mk
deleted file mode 100644
index ad8c781..0000000
--- a/latest/Firmware/Bootloader/L412 (Shrunk)/startup/subdir.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-S_UPPER_SRCS += \
-../startup/startup_stm32l432xx.S
-
-OBJS += \
-./startup/startup_stm32l432xx.o
-
-S_UPPER_DEPS += \
-./startup/startup_stm32l432xx.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-startup/%.o: ../startup/%.S startup/subdir.mk
- @echo 'Building file: $<'
- @echo 'Invoking: GNU ARM Cross Assembler'
- arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -flto -Wall -x assembler-with-cpp -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -c -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
diff --git a/latest/Firmware/Bootloader/Python/bootloader-py3.py b/latest/Firmware/Bootloader/Python/bootloader-py3.py
new file mode 100644
index 0000000..9143843
--- /dev/null
+++ b/latest/Firmware/Bootloader/Python/bootloader-py3.py
@@ -0,0 +1,333 @@
+import serial
+import sys
+import time
+import os
+
+ACK = 0x79
+NACK = 0x1F
+GET = 0x00
+
+PAGE_SIZE = 2048
+FLASH_BASE = 0x08000000
+BAUD_RATE = 115200
+MAX_IMAGE_SIZE = 128*1024
+
+# These defaults will be overwritten with results of GET command
+GET_VER_CMD = 0x01
+GET_ID_CMD = 0x02
+READ_MEM_CMD = 0x11
+GO_CMD = 0x21
+WRITE_MEM_CMD = 0x31
+ERASE_CMD = 0x43 # This may me 0x44 in some chips
+WRITE_PROT_CMD = 0x63
+WRITE_UNPROT_CMD = 0x73
+READ_PROT_CMD = 0x82
+READ_UNPROT_CMD = 0x92
+
+"""
+def print_packet(d):
+ for c in d:
+ sys.stdout.write("0x{:02x} ".format(c))
+ sys.stdout.write('\n')
+"""
+
+error = "No error"
+
+def configure_commands(data):
+ global GET_VER_CMD
+ global GET_ID_CMD
+ global READ_MEM_CMD
+ global GO_CMD
+ global WRITE_MEM_CMD
+ global ERASE_CMD
+ global WRITE_PROT_CMD
+ global WRITE_UNPROT_CMD
+ global READ_PROT_CMD
+ global READ_UNPROT_CMD
+
+ GET_VER_CMD = data[0]
+ GET_ID_CMD = data[1]
+ READ_MEM_CMD = data[2]
+ GO_CMD = data[3]
+ WRITE_MEM_CMD = data[4]
+ ERASE_CMD = data[5]
+ WRITE_PROT_CMD = data[6]
+ WRITE_UNPROT_CMD = data[7]
+ READ_PROT_CMD = data[8]
+ READ_UNPROT_CMD = data[9]
+
+ """
+ s = "Commands: "
+ s += "".join(["0x%x "%d for d in data])
+ print s
+ """
+
+
+def packet_checksum(p):
+ x = 0
+ for b in p:
+ x ^= b
+
+ return x
+
+def read_byte(port):
+ r = port.read(1)
+ if len(r) > 0:
+ return (True, r[0])
+ else:
+ return (False, 0)
+
+def drain(port):
+ keepreading = True
+ while True:
+ (r, keepreading) = read_byte(port)
+ if r == False:
+ break
+
+def do_handshake(port):
+ port.write([0x7f])
+ (success, b) = read_byte(port)
+ if not success:
+ return False
+
+ return b == ACK
+
+def complement(cmd):
+ c = ~cmd
+ if c < 0:
+ c += 256
+ return c
+
+def send_command(port, cmd):
+ packet = [cmd, complement(cmd)]
+ #print packet
+ port.write(packet)
+ (success, r) = read_byte(port)
+ #print r
+ if not success:
+ #print("Failed to send command 0x{0:2x}".format(cmd))
+ return False
+
+ if r != ACK:
+ #print("Got NACK for command 0x{0:2x}".format(cmd))
+ return False
+
+ #print "Got ACK"
+ return True
+
+
+def send_data(port, packet):
+ port.write(packet)
+ (success, b) = read_byte(port)
+ if not success:
+ #print("No ACK or NACK for data packet")
+ return False
+
+ if b == ACK:
+ return True
+ else:
+ #print("Got NACK for data packet")
+ return False
+
+
+def send_get(port):
+ if not send_command(port, GET):
+ #print("Failed to send command GET")
+ return (False, [])
+
+ (success, bytes) = read_byte(port)
+
+ if success:
+ bytes += 1
+ else:
+ return (False, [])
+
+ data = port.read(bytes)
+ if len(data) < bytes:
+ return (False, [])
+
+ (success, b) = read_byte(port)
+ if not success:
+ return (False, [])
+
+ ba = bytearray()
+ ba.extend(data)
+
+ return (b == ACK, ba)
+
+
+def hibyte(s):
+ return s >> 8
+
+def lobyte(s):
+ return s & 0xFF
+
+def send_erase_cmd(startpage, numpages):
+ return False
+
+def send_ext_erase_cmd(port, startpage, numpages):
+ if not send_command(port, ERASE_CMD):
+ return False
+
+ packet = bytearray()
+ packet.append(hibyte(numpages-1))
+ packet.append(lobyte(numpages-1))
+
+ for p in range(startpage, startpage+numpages):
+ packet.append(hibyte(p))
+ packet.append(lobyte(p))
+
+ packet.append(packet_checksum(packet))
+
+ #print "Sending packet:"
+ #print_packet(packet)
+
+ if not send_data(port, packet):
+ return False
+ else:
+ return True
+
+def write_chunk(port, address, chunk):
+ #print "Writing chunk at 0x{0:08x}".format(address)
+ if not send_command(port, WRITE_MEM_CMD):
+ return False
+
+ #print "Sending address"
+ packet = bytearray()
+ packet.append(address >> 24)
+ packet.append((address >> 16) & 0xff)
+ packet.append((address >> 8) & 0xff)
+ packet.append(address & 0xff)
+ packet.append(packet_checksum(packet))
+ if not send_data(port, packet):
+ return False
+
+ #print "Sending chunk"
+ packet = bytearray()
+ packet.append(len(chunk)-1)
+ packet.extend(chunk)
+ packet.append(packet_checksum(packet))
+ return send_data(port, packet)
+
+def boot(port, address):
+ if not send_command(port, GO_CMD):
+ return False
+
+ packet = bytearray()
+ packet.append(address >> 24)
+ packet.append((address >> 16) & 0xff)
+ packet.append((address >> 8) & 0xff)
+ packet.append(address & 0xff)
+ packet.append(packet_checksum(packet))
+ if not send_data(port, packet):
+ return False
+
+ return True
+
+
+def programFirmware(portname, filename):
+ address = FLASH_BASE # Always!
+
+ global error
+
+ st = os.stat(filename)
+ if st.st_size > MAX_IMAGE_SIZE:
+ error = "Image file too large"
+ return False
+
+ port = serial.Serial(portname, baudrate=BAUD_RATE, timeout=2, parity=serial.PARITY_EVEN, stopbits=1)
+ if port is None or not port.is_open:
+ error = "Failed to open port"
+ return False
+
+ bl_present = False
+ for i in range(5):
+ if do_handshake(port):
+ #print("Bootloader is present")
+ bl_present = True
+ break
+ else:
+ pass
+ #print("No response from bootloader")
+
+ if not bl_present:
+ port.close()
+ error = "No response from MCU bootloader"
+ return False
+
+ drain(port)
+
+ (success, data) = send_get(port)
+ if success:
+ configure_commands(data[2:])
+ else:
+ #print("Failed to configure command table")
+ error = "Failed to configure command table"
+ port.close()
+ return False
+
+
+ startpage = 0
+ numpages = int(st.st_size / PAGE_SIZE)
+ if st.st_size % PAGE_SIZE > 0:
+ numpages += 1
+
+ if ERASE_CMD == 0x43:
+ r = send_erase_cmd(port, startpage, numpages)
+ else:
+ r = send_ext_erase_cmd(port, startpage, numpages)
+
+
+ if r == False:
+ #print("Failed to erase pages")
+ pass
+ else:
+ #print("Erased {0} flash pages".format(numpages))
+ pass
+
+
+ addr = address
+ with open(filename, "rb") as f:
+ while True:
+ chunk = f.read(256)
+ if len(chunk) == 0:
+ break
+
+ rem = len(chunk) % 4
+ for i in range(rem):
+ chunk += 0xff
+
+ if not write_chunk(port, addr, chunk):
+ #print("Write failed")
+ port.close()
+ error = "Write failed"
+ return False
+
+ addr += len(chunk)
+
+ sys.stdout.write("Flashing: {0:3d}%\r".format(int(100*(addr-address)/st.st_size)))
+ sys.stdout.flush()
+
+ print()
+
+ if not boot(port, address):
+ error = "Failed to send GO command"
+ port.close()
+ return False
+
+ port.close()
+ return True
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print("Usage: {0} port image".format(sys.argv[0]))
+ sys.exit(1)
+
+ if not programFirmware(sys.argv[1], sys.argv[2]):
+ print("Error: {}".format(error))
+
+
+
+
+
+
diff --git a/latest/Firmware/Transponder/.cproject b/latest/Firmware/Transponder/.cproject
index ab9c03e..cb129e6 100644
--- a/latest/Firmware/Transponder/.cproject
+++ b/latest/Firmware/Transponder/.cproject
@@ -167,7 +167,7 @@
-
+
@@ -341,7 +341,7 @@
-
+
@@ -517,7 +517,7 @@
-
+
@@ -693,7 +693,7 @@
-
+
@@ -871,7 +871,7 @@
-
+
@@ -1049,7 +1049,7 @@
-
+
@@ -1225,7 +1225,7 @@
-
+
@@ -1401,7 +1401,7 @@
-
+
@@ -1581,7 +1581,7 @@
-
+
@@ -1757,7 +1757,7 @@
-
+
@@ -1935,7 +1935,7 @@
-
+
@@ -2113,7 +2113,7 @@
-
+
@@ -2291,7 +2291,7 @@
-
+
diff --git a/latest/Firmware/Transponder/.settings/org.eclipse.cdt.core.prefs b/latest/Firmware/Transponder/.settings/org.eclipse.cdt.core.prefs
index ee44da7..1bd7bc8 100644
--- a/latest/Firmware/Transponder/.settings/org.eclipse.cdt.core.prefs
+++ b/latest/Firmware/Transponder/.settings/org.eclipse.cdt.core.prefs
@@ -17,7 +17,7 @@ indexer/skipIncludedFilesLargerThanMB=16
indexer/skipMacroReferences=false
indexer/skipReferences=false
indexer/skipTypeReferences=false
-indexer/useHeuristicIncludeResolution=true
+indexer/useHeuristicIncludeResolution=false
org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.cdt.core.formatter.alignment_for_assignment=16
org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration=80
diff --git a/latest/Firmware/Transponder/Inc/config.h b/latest/Firmware/Transponder/Inc/config.h
index 81011a0..edef28b 100644
--- a/latest/Firmware/Transponder/Inc/config.h
+++ b/latest/Firmware/Transponder/Inc/config.h
@@ -25,7 +25,7 @@
#include "TXPowerSettings.h"
-#define FW_REV "4.2.0"
+#define FW_REV "4.3.0"
/*
diff --git a/latest/Firmware/Transponder/Python/fwupdate-py3.py b/latest/Firmware/Transponder/Python/fwupdate-py3.py
new file mode 100755
index 0000000..16e844e
--- /dev/null
+++ b/latest/Firmware/Transponder/Python/fwupdate-py3.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+import serial
+import sys
+import os
+import time
+import struct
+import binascii
+
+port = None
+file = None
+filesize = 0
+crc32 = 0
+
+def is_unit_running():
+ print("Checking if unit is running")
+ s = port.readline().strip().decode('utf-8')
+ if len(s) > 0:
+ #print s
+ tokens = s.split(',')
+ if len(tokens) > 3:
+ return True
+ return False
+
+def drain_port():
+ s = port.readline()
+ while len(s) > 0:
+ s = port.readline()
+
+def enable_dfu():
+ if is_unit_running():
+ print("Unit is running, switching to DFU mode")
+ port.write(b'dfu\r\n')
+ drain_port()
+
+ for x in range(5):
+ port.write(b'\r\n')
+ s = port.readline().strip()
+ if s.find(b"MAIANA bootloader") >= 0:
+ return True
+
+ return False
+
+
+
+def begin_transfer():
+ command = "load {0} {1:x}\r\n".format(filesize, crc32).encode('utf-8')
+ port.write(command)
+
+ s = port.readline().strip()
+ return s == b"READY"
+
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print("Usage: {0} port imagefile".format(sys.argv[0]))
+ sys.exit(1)
+
+ portname = sys.argv[1]
+ filename = sys.argv[2]
+
+ port = serial.Serial(portname, 38400, timeout=2)
+ if not port.is_open:
+ print("Unable to open serial port")
+ sys.exit(2)
+
+ file = None
+
+ try:
+ file = open(filename, "rb")
+ except:
+ print("Unable to open file {0}".format(filename))
+ sys.exit(2)
+
+ filesize = os.stat(filename).st_size
+ #print filesize
+ data = file.read()
+ crc32 = (binascii.crc32(data) & 0xFFFFFFFF)
+ file.seek(0)
+
+ print("File size: {0}, CRC32: 0x{1:x}".format(filesize, crc32))
+
+
+ if not enable_dfu():
+ print ("Could not get unit into DFU mode")
+ sys.exit(3)
+
+ print("Unit is in DFU mode")
+
+
+ if not begin_transfer():
+ print("Unable to begin transfer, restart the unit and retry")
+ sys.exit(3)
+
+ print("Starting transfer")
+
+ bytes = file.read(2048)
+ resp = ''
+ while len(bytes) > 0:
+ port.write(bytes)
+ #print "Sent {0} bytes".format(len(bytes))
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ resp = port.readline().strip()
+ if resp.find(b"OK") < 0:
+ break
+ #print s
+ bytes = file.read(2048)
+
+ print()
+ print(resp.decode('utf-8'))
+
+
+
diff --git a/latest/Firmware/Transponder/Python/stm32-bootloader-py3.py b/latest/Firmware/Transponder/Python/stm32-bootloader-py3.py
new file mode 100644
index 0000000..9143843
--- /dev/null
+++ b/latest/Firmware/Transponder/Python/stm32-bootloader-py3.py
@@ -0,0 +1,333 @@
+import serial
+import sys
+import time
+import os
+
+ACK = 0x79
+NACK = 0x1F
+GET = 0x00
+
+PAGE_SIZE = 2048
+FLASH_BASE = 0x08000000
+BAUD_RATE = 115200
+MAX_IMAGE_SIZE = 128*1024
+
+# These defaults will be overwritten with results of GET command
+GET_VER_CMD = 0x01
+GET_ID_CMD = 0x02
+READ_MEM_CMD = 0x11
+GO_CMD = 0x21
+WRITE_MEM_CMD = 0x31
+ERASE_CMD = 0x43 # This may me 0x44 in some chips
+WRITE_PROT_CMD = 0x63
+WRITE_UNPROT_CMD = 0x73
+READ_PROT_CMD = 0x82
+READ_UNPROT_CMD = 0x92
+
+"""
+def print_packet(d):
+ for c in d:
+ sys.stdout.write("0x{:02x} ".format(c))
+ sys.stdout.write('\n')
+"""
+
+error = "No error"
+
+def configure_commands(data):
+ global GET_VER_CMD
+ global GET_ID_CMD
+ global READ_MEM_CMD
+ global GO_CMD
+ global WRITE_MEM_CMD
+ global ERASE_CMD
+ global WRITE_PROT_CMD
+ global WRITE_UNPROT_CMD
+ global READ_PROT_CMD
+ global READ_UNPROT_CMD
+
+ GET_VER_CMD = data[0]
+ GET_ID_CMD = data[1]
+ READ_MEM_CMD = data[2]
+ GO_CMD = data[3]
+ WRITE_MEM_CMD = data[4]
+ ERASE_CMD = data[5]
+ WRITE_PROT_CMD = data[6]
+ WRITE_UNPROT_CMD = data[7]
+ READ_PROT_CMD = data[8]
+ READ_UNPROT_CMD = data[9]
+
+ """
+ s = "Commands: "
+ s += "".join(["0x%x "%d for d in data])
+ print s
+ """
+
+
+def packet_checksum(p):
+ x = 0
+ for b in p:
+ x ^= b
+
+ return x
+
+def read_byte(port):
+ r = port.read(1)
+ if len(r) > 0:
+ return (True, r[0])
+ else:
+ return (False, 0)
+
+def drain(port):
+ keepreading = True
+ while True:
+ (r, keepreading) = read_byte(port)
+ if r == False:
+ break
+
+def do_handshake(port):
+ port.write([0x7f])
+ (success, b) = read_byte(port)
+ if not success:
+ return False
+
+ return b == ACK
+
+def complement(cmd):
+ c = ~cmd
+ if c < 0:
+ c += 256
+ return c
+
+def send_command(port, cmd):
+ packet = [cmd, complement(cmd)]
+ #print packet
+ port.write(packet)
+ (success, r) = read_byte(port)
+ #print r
+ if not success:
+ #print("Failed to send command 0x{0:2x}".format(cmd))
+ return False
+
+ if r != ACK:
+ #print("Got NACK for command 0x{0:2x}".format(cmd))
+ return False
+
+ #print "Got ACK"
+ return True
+
+
+def send_data(port, packet):
+ port.write(packet)
+ (success, b) = read_byte(port)
+ if not success:
+ #print("No ACK or NACK for data packet")
+ return False
+
+ if b == ACK:
+ return True
+ else:
+ #print("Got NACK for data packet")
+ return False
+
+
+def send_get(port):
+ if not send_command(port, GET):
+ #print("Failed to send command GET")
+ return (False, [])
+
+ (success, bytes) = read_byte(port)
+
+ if success:
+ bytes += 1
+ else:
+ return (False, [])
+
+ data = port.read(bytes)
+ if len(data) < bytes:
+ return (False, [])
+
+ (success, b) = read_byte(port)
+ if not success:
+ return (False, [])
+
+ ba = bytearray()
+ ba.extend(data)
+
+ return (b == ACK, ba)
+
+
+def hibyte(s):
+ return s >> 8
+
+def lobyte(s):
+ return s & 0xFF
+
+def send_erase_cmd(startpage, numpages):
+ return False
+
+def send_ext_erase_cmd(port, startpage, numpages):
+ if not send_command(port, ERASE_CMD):
+ return False
+
+ packet = bytearray()
+ packet.append(hibyte(numpages-1))
+ packet.append(lobyte(numpages-1))
+
+ for p in range(startpage, startpage+numpages):
+ packet.append(hibyte(p))
+ packet.append(lobyte(p))
+
+ packet.append(packet_checksum(packet))
+
+ #print "Sending packet:"
+ #print_packet(packet)
+
+ if not send_data(port, packet):
+ return False
+ else:
+ return True
+
+def write_chunk(port, address, chunk):
+ #print "Writing chunk at 0x{0:08x}".format(address)
+ if not send_command(port, WRITE_MEM_CMD):
+ return False
+
+ #print "Sending address"
+ packet = bytearray()
+ packet.append(address >> 24)
+ packet.append((address >> 16) & 0xff)
+ packet.append((address >> 8) & 0xff)
+ packet.append(address & 0xff)
+ packet.append(packet_checksum(packet))
+ if not send_data(port, packet):
+ return False
+
+ #print "Sending chunk"
+ packet = bytearray()
+ packet.append(len(chunk)-1)
+ packet.extend(chunk)
+ packet.append(packet_checksum(packet))
+ return send_data(port, packet)
+
+def boot(port, address):
+ if not send_command(port, GO_CMD):
+ return False
+
+ packet = bytearray()
+ packet.append(address >> 24)
+ packet.append((address >> 16) & 0xff)
+ packet.append((address >> 8) & 0xff)
+ packet.append(address & 0xff)
+ packet.append(packet_checksum(packet))
+ if not send_data(port, packet):
+ return False
+
+ return True
+
+
+def programFirmware(portname, filename):
+ address = FLASH_BASE # Always!
+
+ global error
+
+ st = os.stat(filename)
+ if st.st_size > MAX_IMAGE_SIZE:
+ error = "Image file too large"
+ return False
+
+ port = serial.Serial(portname, baudrate=BAUD_RATE, timeout=2, parity=serial.PARITY_EVEN, stopbits=1)
+ if port is None or not port.is_open:
+ error = "Failed to open port"
+ return False
+
+ bl_present = False
+ for i in range(5):
+ if do_handshake(port):
+ #print("Bootloader is present")
+ bl_present = True
+ break
+ else:
+ pass
+ #print("No response from bootloader")
+
+ if not bl_present:
+ port.close()
+ error = "No response from MCU bootloader"
+ return False
+
+ drain(port)
+
+ (success, data) = send_get(port)
+ if success:
+ configure_commands(data[2:])
+ else:
+ #print("Failed to configure command table")
+ error = "Failed to configure command table"
+ port.close()
+ return False
+
+
+ startpage = 0
+ numpages = int(st.st_size / PAGE_SIZE)
+ if st.st_size % PAGE_SIZE > 0:
+ numpages += 1
+
+ if ERASE_CMD == 0x43:
+ r = send_erase_cmd(port, startpage, numpages)
+ else:
+ r = send_ext_erase_cmd(port, startpage, numpages)
+
+
+ if r == False:
+ #print("Failed to erase pages")
+ pass
+ else:
+ #print("Erased {0} flash pages".format(numpages))
+ pass
+
+
+ addr = address
+ with open(filename, "rb") as f:
+ while True:
+ chunk = f.read(256)
+ if len(chunk) == 0:
+ break
+
+ rem = len(chunk) % 4
+ for i in range(rem):
+ chunk += 0xff
+
+ if not write_chunk(port, addr, chunk):
+ #print("Write failed")
+ port.close()
+ error = "Write failed"
+ return False
+
+ addr += len(chunk)
+
+ sys.stdout.write("Flashing: {0:3d}%\r".format(int(100*(addr-address)/st.st_size)))
+ sys.stdout.flush()
+
+ print()
+
+ if not boot(port, address):
+ error = "Failed to send GO command"
+ port.close()
+ return False
+
+ port.close()
+ return True
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print("Usage: {0} port image".format(sys.argv[0]))
+ sys.exit(1)
+
+ if not programFirmware(sys.argv[1], sys.argv[2]):
+ print("Error: {}".format(error))
+
+
+
+
+
+
diff --git a/latest/Firmware/Transponder/Python/bootloader.py b/latest/Firmware/Transponder/Python/stm32-bootloader.py
similarity index 100%
rename from latest/Firmware/Transponder/Python/bootloader.py
rename to latest/Firmware/Transponder/Python/stm32-bootloader.py