...
diff --git a/32blit-stm32/Src/usb-serial.cpp b/32blit-stm32/Src/usb-serial.cpp
index c68a8d5..b373299 100644
--- a/32blit-stm32/Src/usb-serial.cpp
+++ b/32blit-stm32/Src/usb-serial.cpp
@@ -87,7 +87,7 @@
std::map<std::string, CommandHandler> handlers;
- constexpr uint32_t MAX_PACKETS = 16;
+ constexpr uint32_t MAX_PACKETS = 64;
Packet packets[MAX_PACKETS];
std::vector<Packet*> free_packets;
@@ -174,7 +174,7 @@
// the command handle must return true when it has finished processing
// the entire command (even if this is across multiple packets)
CommandState result = handler(CommandState::STREAM, packet->data, packet->length);
-
+
if(result == CommandState::END) {
// command stream is complete, detach handler
handler = nullptr;
diff --git a/32blit.toolchain b/32blit.toolchain
index 30feb5f..4df35df 100644
--- a/32blit.toolchain
+++ b/32blit.toolchain
@@ -37,7 +37,6 @@
set(CMAKE_C_FLAGS_INIT "${COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS_INIT "${COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-g -Og")
-#set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -T ${MCU_LINKER_SCRIPT} -Wl,--gc-sections")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nosys.specs -Wl,--gc-sections,--no-wchar-size-warning")
diff --git a/examples/flash b/examples/flash
index a7136a0..786c751 100644
--- a/examples/flash
+++ b/examples/flash
@@ -7,20 +7,23 @@
import os
import os.path
import time
+import threading
from tqdm import tqdm
parser = argparse.ArgumentParser(description='32blit binary flasher.')
-parser.add_argument("file", help="Path to the binary file (e.g. 'build.stm32/voxel.bin')")
+parser.add_argument("command", help="Command to perform (e.g. 'save', 'dfu', 'reset')", default="save")
parser.add_argument("port", help="Name of the serial port (e.g. 'COM4', '/dev/ttyS4', etc.)")
parser.add_argument("--target", help="Target either 'sd' or 'flash'", default="sd", choices=["sd", "flash"])
+parser.add_argument("--no-read", help="Do not wait to read responses", action="store_true")
+parser.add_argument("file", help="Path to the binary file (e.g. 'build.stm32/voxel.bin')", nargs='?')
args = parser.parse_args()
print("32blit binary flasher.")
port = args.port
+command = args.command
target = args.target
-path = args.file
valid_ports = [port[0] for port in serial.tools.list_ports.comports()]
@@ -28,40 +31,83 @@
print("Specified port '{0}' not valid".format(port))
sys.exit(os.EX_OSFILE)
-if not os.path.isfile(path):
- print("Specified binary file '{0}' does not exist".format(path))
- sys.exit(os.EX_NOINPUT)
-
serial_port = None
try:
serial_port = serial.Serial(port, 115200, timeout=1)
+ serial_port.reset_output_buffer()
except OSError:
print("Could not open port '{0}'".format(port))
print("The port may not exist or you may not have permission to access it.")
sys.exit(os.EX_OSFILE)
-file_size = os.stat(path).st_size
-file_name = os.path.basename(path)
-sent_byte_count = 0
-chunk_size = 64
+if not args.no_read:
+ # read thread constantly polls for responses from 32blit and
+ # outputs them to the screen
+ def read_serial(serial_port):
+ while True:
+ data = serial_port.read_until(b"\0").decode()
+ if data:
+ print(data)
-# such reset, very boot
-#serial_port.write(b"32BL_RST\x00")
-#sys.exit()
+ read_thread = threading.Thread(target=read_serial, args=(serial_port,))
+ read_thread.start()
-serial_port.reset_output_buffer()
+print(command)
-command = "SAVE\x00{0}\x00{1}\x00".format(file_name, file_size)
-serial_port.write(bytes(command, "ascii"))
+if command == "save":
+ path = args.file
+ if not os.path.isfile(path):
+ print("Specified binary file '{0}' does not exist".format(path))
+ sys.exit(os.EX_NOINPUT)
-with open(path, "rb") as f:
- progress = tqdm(total=file_size, desc="Flashing...", unit_scale=True, unit_divisor=1024, unit="B", ncols=70, dynamic_ncols=True)
+ file_size = os.stat(path).st_size
+ file_name = os.path.basename(path)
- while sent_byte_count < file_size:
- data = f.read(chunk_size)
- serial_port.write(data)
- sent_byte_count += chunk_size
- progress.update(chunk_size)
-
- progress.close()
\ No newline at end of file
+ # send the save command to 32blit
+ data = "SAVE\x00{0}\x00{1}\x00".format(file_name, file_size)
+ serial_port.write(bytes(data, "ascii"))
+
+ # transmit the file data to 32blit
+ sent_byte_count = 0
+ chunk_size = 64
+ with open(path, "rb") as f:
+ progress = tqdm(total=file_size, desc="Flashing...", unit_scale=True, unit_divisor=1024, unit="B", ncols=70, dynamic_ncols=True)
+
+ while sent_byte_count < file_size:
+ # last chunk may be smaller than 64 bytes
+ if file_size - sent_byte_count < chunk_size:
+ chunk_size = file_size - sent_byte_count
+
+ # read chunk from file
+ data = f.read(chunk_size)
+
+ # transmit it to 32blit
+ serial_port.write(data)
+ sent_byte_count += chunk_size
+
+ # update progress bar
+ progress.update(chunk_size)
+
+ progress.close()
+
+if command == "dfu":
+ # send the dfu command to 32blit
+ data = "DFU\x00"
+ serial_port.write(bytes(data, "ascii"))
+
+if command == "reset":
+ # send the dfu command to 32blit
+ data = "RESET\x00"
+ serial_port.write(bytes(data, "ascii"))
+
+if not args.no_read:
+ # wait for any responses
+ print("Reading responses from 32blit. Press Ctrl+C to quit.")
+ try:
+ while True:
+ pass
+ except KeyboardInterrupt:
+ read_thread.stop()
+
+time.sleep(1)
\ No newline at end of file
diff --git a/firmware/firmware.cpp b/firmware/firmware.cpp
index a5aac92..995d886 100644
--- a/firmware/firmware.cpp
+++ b/firmware/firmware.cpp
@@ -54,14 +54,23 @@
Vec2 list_offset(5.0f, 0.0f);
-CommandState usb_cdc_save_to_sd_card(CommandState state, char *data, uint32_t length);
+CommandState usb_serial_save_to_sd_card(CommandState state, char *data, uint32_t length);
-CommandState usb_cdc_reset(CommandState state, char *data, uint32_t length) {
+CommandState usb_serial_reset(CommandState state, char *data, uint32_t length) {
NVIC_SystemReset();
return CommandState::END;
}
-CommandState usb_cdc_application_location(CommandState state, char *data, uint32_t length) {
+CommandState usb_serial_dfu(CommandState state, char *data, uint32_t length) {
+ *((uint32_t *)0x2001FFFC) = 0xCAFEBABE;
+
+ SCB_CleanDCache();
+ NVIC_SystemReset();
+
+ return CommandState::END;
+}
+
+CommandState usb_serial_application_location(CommandState state, char *data, uint32_t length) {
while(USBD_BUSY == transmit("32BL_EXT")) {};
HAL_Delay(250);
return CommandState::END;
@@ -73,9 +82,10 @@
set_screen_mode(ScreenMode::hires);
load_file_list();
- register_command_handler("RESET", usb_cdc_reset);
- register_command_handler("INFO", usb_cdc_application_location);
- register_command_handler("SAVE", usb_cdc_save_to_sd_card);
+ register_command_handler("RESET", usb_serial_reset);
+ register_command_handler( "INFO", usb_serial_application_location);
+ register_command_handler( "SAVE", usb_serial_save_to_sd_card);
+ register_command_handler( "DFU", usb_serial_dfu);
}
void background(uint32_t time_ms) {
@@ -193,7 +203,7 @@
bool flash_from_sd_to_qspi_flash(const std::string &filename)
{
- static uint8_t file_buffer[4 * 1024];
+ static uint8_t file_buffer[256];
FIL file;
if(f_open(&file, filename.c_str(), FA_READ) != FR_OK) {
@@ -248,7 +258,7 @@
// when a command is issued (e.g. "PROG" or "SAVE") then this function is called
// whenever new data is received to allow the firmware to process it.
-CommandState usb_cdc_save_to_sd_card(CommandState state, char *data, uint32_t length) {
+CommandState usb_serial_save_to_sd_card(CommandState state, char *data, uint32_t length) {
static char filename[64] = {'\0'};
static FIL file;
@@ -301,6 +311,8 @@
f_close(&file);
return CommandState::ERROR;
}
+
+ //f_sync(&file);
bytes_processed += bytes_written;
@@ -310,6 +322,7 @@
load_file_list();
select_file(filename);
f_close(&file);
+
memset(filename, 0, sizeof(filename));
return CommandState::END;
}else{