1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-06-05 09:10:30 -07:00

Checkpoint

This commit is contained in:
Peter Antypas 2023-02-25 20:11:54 -08:00
parent 2df4e596e2
commit d820455b4a
4 changed files with 122 additions and 137 deletions

View File

@ -1,12 +1,8 @@
#!/usr/bin/env python
import serial import serial
import sys import sys
import time import time
import os import os
port = None
ACK = 0x79 ACK = 0x79
NACK = 0x1F NACK = 0x1F
GET = 0x00 GET = 0x00
@ -14,7 +10,7 @@ GET = 0x00
PAGE_SIZE = 2048 PAGE_SIZE = 2048
FLASH_BASE = 0x08000000 FLASH_BASE = 0x08000000
BAUD_RATE = 115200 BAUD_RATE = 115200
MAX_IMAGE_SIZE = 64*1024 MAX_IMAGE_SIZE = 128*1024
# These defaults will be overwritten with results of GET command # These defaults will be overwritten with results of GET command
GET_VER_CMD = 0x01 GET_VER_CMD = 0x01
@ -28,10 +24,14 @@ WRITE_UNPROT_CMD = 0x73
READ_PROT_CMD = 0x82 READ_PROT_CMD = 0x82
READ_UNPROT_CMD = 0x92 READ_UNPROT_CMD = 0x92
"""
def print_packet(d): def print_packet(d):
for c in d: for c in d:
sys.stdout.write("0x{:02x} ".format(c)) sys.stdout.write("0x{:02x} ".format(c))
sys.stdout.write('\n') sys.stdout.write('\n')
"""
error = "No error"
def configure_commands(data): def configure_commands(data):
global GET_VER_CMD global GET_VER_CMD
@ -70,23 +70,23 @@ def packet_checksum(p):
return x return x
def read_byte(): def read_byte(port):
r = port.read(1) r = port.read(1)
if len(r) > 0: if len(r) > 0:
return (True, ord(r[0])) return (True, r[0])
else: else:
return (False, 0) return (False, 0)
def drain(): def drain(port):
keepreading = True keepreading = True
while True: while True:
(r, keepreading) = read_byte() (r, keepreading) = read_byte(port)
if r == False: if r == False:
break break
def do_handshake(): def do_handshake(port):
port.write([0x7f]) port.write([0x7f])
(success, b) = read_byte() (success, b) = read_byte(port)
if not success: if not success:
return False return False
@ -98,51 +98,44 @@ def complement(cmd):
c += 256 c += 256
return c return c
def send_command(cmd): def send_command(port, cmd):
packet = [cmd, complement(cmd)] packet = [cmd, complement(cmd)]
#print packet #print packet
port.write(packet) port.write(packet)
(success, r) = read_byte() (success, r) = read_byte(port)
#print r #print r
if not success: if not success:
print "Failed to send command 0x{0:2x}".format(cmd) #print("Failed to send command 0x{0:2x}".format(cmd))
return False return False
if r != ACK: if r != ACK:
print "Got NACK for command 0x{0:2x}".format(cmd) #print("Got NACK for command 0x{0:2x}".format(cmd))
return False return False
#print "Got ACK" #print "Got ACK"
return True return True
def send_data(packet): def send_data(port, packet):
port.write(packet) port.write(packet)
(success, b) = read_byte() (success, b) = read_byte(port)
if not success: if not success:
print "No ACK or NACK for data packet" #print("No ACK or NACK for data packet")
return False return False
if b == ACK: if b == ACK:
return True return True
else: else:
print "Got NACK for data packet" #print("Got NACK for data packet")
return False return False
def send_get(): def send_get(port):
success = False if not send_command(port, GET):
for i in range(2): #print("Failed to send command GET")
if send_command(GET):
success = True
break
time.sleep(.2)
if not success:
print "Failed to send command GET"
return (False, []) return (False, [])
(success, bytes) = read_byte() (success, bytes) = read_byte(port)
if success: if success:
bytes += 1 bytes += 1
@ -153,13 +146,13 @@ def send_get():
if len(data) < bytes: if len(data) < bytes:
return (False, []) return (False, [])
(success, b) = read_byte() (success, b) = read_byte(port)
if not success: if not success:
return (False, []) return (False, [])
ba = bytearray() ba = bytearray()
ba.extend(data) ba.extend(data)
#print ba
return (b == ACK, ba) return (b == ACK, ba)
@ -172,8 +165,8 @@ def lobyte(s):
def send_erase_cmd(startpage, numpages): def send_erase_cmd(startpage, numpages):
return False return False
def send_ext_erase_cmd(startpage, numpages): def send_ext_erase_cmd(port, startpage, numpages):
if not send_command(ERASE_CMD): if not send_command(port, ERASE_CMD):
return False return False
packet = bytearray() packet = bytearray()
@ -189,14 +182,14 @@ def send_ext_erase_cmd(startpage, numpages):
#print "Sending packet:" #print "Sending packet:"
#print_packet(packet) #print_packet(packet)
if not send_data(packet): if not send_data(port, packet):
return False return False
else: else:
return True return True
def write_chunk(address, chunk): def write_chunk(port, address, chunk):
#print "Writing chunk at 0x{0:08x}".format(address) #print "Writing chunk at 0x{0:08x}".format(address)
if not send_command(WRITE_MEM_CMD): if not send_command(port, WRITE_MEM_CMD):
return False return False
#print "Sending address" #print "Sending address"
@ -206,7 +199,7 @@ def write_chunk(address, chunk):
packet.append((address >> 8) & 0xff) packet.append((address >> 8) & 0xff)
packet.append(address & 0xff) packet.append(address & 0xff)
packet.append(packet_checksum(packet)) packet.append(packet_checksum(packet))
if not send_data(packet): if not send_data(port, packet):
return False return False
#print "Sending chunk" #print "Sending chunk"
@ -214,10 +207,10 @@ def write_chunk(address, chunk):
packet.append(len(chunk)-1) packet.append(len(chunk)-1)
packet.extend(chunk) packet.extend(chunk)
packet.append(packet_checksum(packet)) packet.append(packet_checksum(packet))
return send_data(packet) return send_data(port, packet)
def boot(address): def boot(port, address):
if not send_command(GO_CMD): if not send_command(port, GO_CMD):
return False return False
packet = bytearray() packet = bytearray()
@ -226,135 +219,116 @@ def boot(address):
packet.append((address >> 8) & 0xff) packet.append((address >> 8) & 0xff)
packet.append(address & 0xff) packet.append(address & 0xff)
packet.append(packet_checksum(packet)) packet.append(packet_checksum(packet))
if not send_data(packet): if not send_data(port, packet):
return False return False
return True return True
"""
def enter_dfu(portname): def programFirmware(portname, filename):
p = serial.Serial(portname, 38400, timeout=2, parity=serial.PARITY_NONE, stopbits=1) address = FLASH_BASE # Always!
if not p.is_open:
global error
st = os.stat(filename)
if st.st_size > MAX_IMAGE_SIZE:
error = "Image file too large"
return False return False
p.write('dfu\r\n') port = serial.Serial(portname, baudrate=BAUD_RATE, timeout=2, parity=serial.PARITY_EVEN, stopbits=1)
time.sleep(1) if port is None or not port.is_open:
s = p.readline() error = "Failed to open port"
p.close() return False
return len(s) == 0
"""
if __name__ == '__main__':
if len(sys.argv) < 4:
print "Usage: {0} port image address".format(sys.argv[0])
sys.exit(1)
# Determine which pages of Flash must be erased to write the image
address = int(sys.argv[3], 16)
if address % PAGE_SIZE:
print "Invalid address: Must be aligned at 2K boundaries"
sys.exit(1)
if not os.path.isfile(sys.argv[2]):
print "File not found: {0}".format(sys.argv[2])
sys.exit(2)
st = os.stat(sys.argv[2])
if st.st_size > MAX_IMAGE_SIZE:
print "Image file too large"
sys.exit(1)
"""
if not enter_dfu(sys.argv[1]):
print "Could not enter DFU mode"
sys.exit(1)
"""
port = serial.Serial(sys.argv[1], BAUD_RATE, timeout=2, parity=serial.PARITY_EVEN, stopbits=1)
if not port.is_open:
print "Failed to open port"
sys.exit(2)
bl_present = False bl_present = False
for i in range(5): for i in range(5):
if do_handshake(): if do_handshake(port):
print "Bootloader is present" #print("Bootloader is present")
bl_present = True bl_present = True
break break
else: else:
print "No response from bootloader" pass
#print("No response from bootloader")
if not bl_present: if not bl_present:
sys.exit(1) port.close()
error = "No response from MCU bootloader"
return False
drain() drain(port)
(success, data) = send_get() (success, data) = send_get(port)
if success: if success:
configure_commands(data[2:]) configure_commands(data[2:])
else: else:
print "Failed to configure command table" #print("Failed to configure command table")
sys.exit(1) error = "Failed to configure command table"
port.close()
return False
startpage = (address - FLASH_BASE)/PAGE_SIZE startpage = 0
numpages = st.st_size / PAGE_SIZE numpages = int(st.st_size / PAGE_SIZE)
if st.st_size % PAGE_SIZE > 0: if st.st_size % PAGE_SIZE > 0:
numpages += 1 numpages += 1
if ERASE_CMD == 0x43: if ERASE_CMD == 0x43:
r = send_erase_cmd(startpage, numpages) r = send_erase_cmd(port, startpage, numpages)
else: else:
r = send_ext_erase_cmd(startpage, numpages) r = send_ext_erase_cmd(port, startpage, numpages)
if r == False: if r == False:
print "Failed to erase pages" #print("Failed to erase pages")
pass
else: else:
print "Erased {0} flash pages".format(numpages) #print("Erased {0} flash pages".format(numpages))
pass
addr = address addr = address
first_chunk = None with open(filename, "rb") as f:
with open(sys.argv[2], "rb") as f:
while True: while True:
chunk = f.read(256) chunk = f.read(256)
if len(chunk) == 0: if len(chunk) == 0:
break break
if addr == address: rem = len(chunk) % 4
# Preserve the first chunk and write it last. for i in range(rem):
# This makes FW update as close to atomic as possible. chunk += 0xff
first_chunk = chunk
else:
rem = len(chunk) % 4
for i in range(rem):
chunk += 0xff
if not write_chunk(addr, chunk): if not write_chunk(port, addr, chunk):
print "Write failed" #print("Write failed")
sys.exit(1) port.close()
error = "Write failed"
return False
addr += len(chunk) addr += len(chunk)
sys.stdout.write("Flashing: {0:3d}%\r".format(100*(addr-address)/st.st_size)) #sys.stdout.write("Flashing: {0:3d}%\r".format(int(100*(addr-address)/st.st_size)))
sys.stdout.flush() #sys.stdout.flush()
if write_chunk(address, first_chunk): #print()
sys.stdout.write("\r\nFlashed boot sector at address 0x{:08x}\r\n".format(address))
sys.stdout.flush() if not boot(port, address):
else: error = "Failed to send GO command"
print "Failed to write boot sector!!!" 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) sys.exit(1)
print if not os.path.isfile(sys.argv[2]):
print("File not found: {0}".format(sys.argv[2]))
sys.exit(2)
programFirmware(sys.argv[1], sys.argv[2])
if not boot(address):
print "Failed to send GO command"
sys.exit(1)
print "Booted"

View File

@ -17,11 +17,13 @@ static StaticTimer_t static_timer;
#define RD_BUF_SIZE (BUF_SIZE) #define RD_BUF_SIZE (BUF_SIZE)
uint8_t dtmp[RD_BUF_SIZE]; uint8_t dtmp[RD_BUF_SIZE];
#define GPIO_UART1_RX GPIO_NUM_25 #define GPIO_UART1_RX GPIO_NUM_25
#define GPIO_UART1_TX GPIO_NUM_26 #define GPIO_UART1_TX GPIO_NUM_26
#define GPIO_TX_BUTTON GPIO_NUM_34 #define GPIO_TX_BUTTON GPIO_NUM_34
#define GPIO_RED_LED GPIO_NUM_5 #define GPIO_RED_LED GPIO_NUM_5
#define GPIO_GREEN_LED GPIO_NUM_4 #define GPIO_GREEN_LED GPIO_NUM_4
#define GPIO_STM32_RESET_N GPIO_NUM_12
#define GPIO_STM32_TX_EN GPIO_NUM_13
void uart_rx_task(void *params) void uart_rx_task(void *params)
{ {
@ -54,7 +56,7 @@ void bsp_uart_init()
uart_driver_install(UART_NUM_1, BUF_SIZE*2, 0, 0, NULL, 0); uart_driver_install(UART_NUM_1, BUF_SIZE*2, 0, 0, NULL, 0);
uart_enable_rx_intr(UART_NUM_1); uart_enable_rx_intr(UART_NUM_1);
xTaskCreate(uart_rx_task, "uart_event_task", 1024, NULL, 5, NULL); xTaskCreate(uart_rx_task, "uart_event_task", 4096, NULL, 5, NULL);
} }
void bsp_set_uart_rx_cb(uart_rx_cb_t *cb) void bsp_set_uart_rx_cb(uart_rx_cb_t *cb)
@ -109,12 +111,20 @@ void bsp_hw_init()
{ {
bsp_uart_init(); bsp_uart_init();
config_gpio(GPIO_TX_BUTTON, GPIO_MODE_INPUT, false, false); //config_gpio(GPIO_TX_BUTTON, GPIO_MODE_INPUT, false, false);
gpio_set_direction(GPIO_TX_BUTTON, GPIO_MODE_INPUT); //gpio_set_direction(GPIO_TX_BUTTON, GPIO_MODE_INPUT);
gpio_set_intr_type(GPIO_TX_BUTTON, GPIO_INTR_NEGEDGE); //gpio_set_intr_type(GPIO_TX_BUTTON, GPIO_INTR_NEGEDGE);
config_gpio(GPIO_RED_LED, GPIO_MODE_OUTPUT, false, false); config_gpio(GPIO_RED_LED, GPIO_MODE_OUTPUT, false, false);
config_gpio(GPIO_GREEN_LED, GPIO_MODE_OUTPUT, false, false); config_gpio(GPIO_GREEN_LED, GPIO_MODE_OUTPUT, false, false);
config_gpio(GPIO_STM32_RESET_N, GPIO_MODE_OUTPUT_OD, false, false);
config_gpio(GPIO_STM32_TX_EN, GPIO_MODE_OUTPUT_OD, false, false);
gpio_set_level(GPIO_STM32_TX_EN, 1);
//gpio_set_level(GPIO_STM32_RESET_N, 0);
//usleep(2000);
//gpio_set_level(GPIO_STM32_RESET_N, 1);
#if 0 #if 0
gpio_set_direction(GPIO_RED_LED, GPIO_MODE_OUTPUT); gpio_set_direction(GPIO_RED_LED, GPIO_MODE_OUTPUT);
@ -124,8 +134,8 @@ void bsp_hw_init()
gpio_set_level(GPIO_GREEN_LED, 1); gpio_set_level(GPIO_GREEN_LED, 1);
#endif #endif
gpio_install_isr_service(0); //gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_TX_BUTTON, btn_isr, NULL); //gpio_isr_handler_add(GPIO_TX_BUTTON, btn_isr, NULL);
bsp_timer_init(); bsp_timer_init();
} }

View File

@ -291,7 +291,7 @@ void nmea_gateway_start()
esp_event_handler_register(MAIANA_EVENT, NMEA_RESTART_EVENT, nmea_restart_handler, NULL); esp_event_handler_register(MAIANA_EVENT, NMEA_RESTART_EVENT, nmea_restart_handler, NULL);
__queue_handle = xQueueCreateStatic(QUEUE_LENGTH, sizeof(serial_message_t), (uint8_t*)__queue_data, &__queue); __queue_handle = xQueueCreateStatic(QUEUE_LENGTH, sizeof(serial_message_t), (uint8_t*)__queue_data, &__queue);
xTaskCreate(nmea_input_task, "nmea", 2048, NULL, 4, &__task_handle); xTaskCreate(nmea_input_task, "nmea", 4096, NULL, 4, &__task_handle);
} }
void nmea_gateway_restart() void nmea_gateway_restart()

View File

@ -5,4 +5,5 @@ otadata, data, ota, , 8K
phy_init, data, phy, , 4K phy_init, data, phy, , 4K
factory, app, factory, , 1536K factory, app, factory, , 1536K
ota_0, app, ota_0, , 1536K ota_0, app, ota_0, , 1536K
storage, data, fat, , 900K ota_1, app, ota_1, , 1536K

1 # Partition Table
5 phy_init, data, phy, , 4K
6 factory, app, factory, , 1536K
7 ota_0, app, ota_0, , 1536K
8 storage, data, fat, , 900K ota_1, app, ota_1, , 1536K
9