1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-06-01 15:20:40 -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 sys
import time
import os
port = None
ACK = 0x79
NACK = 0x1F
GET = 0x00
@ -14,7 +10,7 @@ GET = 0x00
PAGE_SIZE = 2048
FLASH_BASE = 0x08000000
BAUD_RATE = 115200
MAX_IMAGE_SIZE = 64*1024
MAX_IMAGE_SIZE = 128*1024
# These defaults will be overwritten with results of GET command
GET_VER_CMD = 0x01
@ -28,10 +24,14 @@ 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
@ -70,23 +70,23 @@ def packet_checksum(p):
return x
def read_byte():
def read_byte(port):
r = port.read(1)
if len(r) > 0:
return (True, ord(r[0]))
return (True, r[0])
else:
return (False, 0)
def drain():
def drain(port):
keepreading = True
while True:
(r, keepreading) = read_byte()
(r, keepreading) = read_byte(port)
if r == False:
break
def do_handshake():
def do_handshake(port):
port.write([0x7f])
(success, b) = read_byte()
(success, b) = read_byte(port)
if not success:
return False
@ -98,51 +98,44 @@ def complement(cmd):
c += 256
return c
def send_command(cmd):
def send_command(port, cmd):
packet = [cmd, complement(cmd)]
#print packet
port.write(packet)
(success, r) = read_byte()
(success, r) = read_byte(port)
#print r
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
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
#print "Got ACK"
return True
def send_data(packet):
def send_data(port, packet):
port.write(packet)
(success, b) = read_byte()
(success, b) = read_byte(port)
if not success:
print "No ACK or NACK for data packet"
#print("No ACK or NACK for data packet")
return False
if b == ACK:
return True
else:
print "Got NACK for data packet"
#print("Got NACK for data packet")
return False
def send_get():
success = False
for i in range(2):
if send_command(GET):
success = True
break
time.sleep(.2)
if not success:
print "Failed to send command GET"
def send_get(port):
if not send_command(port, GET):
#print("Failed to send command GET")
return (False, [])
(success, bytes) = read_byte()
(success, bytes) = read_byte(port)
if success:
bytes += 1
@ -153,13 +146,13 @@ def send_get():
if len(data) < bytes:
return (False, [])
(success, b) = read_byte()
(success, b) = read_byte(port)
if not success:
return (False, [])
ba = bytearray()
ba.extend(data)
#print ba
return (b == ACK, ba)
@ -172,8 +165,8 @@ def lobyte(s):
def send_erase_cmd(startpage, numpages):
return False
def send_ext_erase_cmd(startpage, numpages):
if not send_command(ERASE_CMD):
def send_ext_erase_cmd(port, startpage, numpages):
if not send_command(port, ERASE_CMD):
return False
packet = bytearray()
@ -189,14 +182,14 @@ def send_ext_erase_cmd(startpage, numpages):
#print "Sending packet:"
#print_packet(packet)
if not send_data(packet):
if not send_data(port, packet):
return False
else:
return True
def write_chunk(address, chunk):
def write_chunk(port, address, chunk):
#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
#print "Sending address"
@ -206,7 +199,7 @@ def write_chunk(address, chunk):
packet.append((address >> 8) & 0xff)
packet.append(address & 0xff)
packet.append(packet_checksum(packet))
if not send_data(packet):
if not send_data(port, packet):
return False
#print "Sending chunk"
@ -214,10 +207,10 @@ def write_chunk(address, chunk):
packet.append(len(chunk)-1)
packet.extend(chunk)
packet.append(packet_checksum(packet))
return send_data(packet)
return send_data(port, packet)
def boot(address):
if not send_command(GO_CMD):
def boot(port, address):
if not send_command(port, GO_CMD):
return False
packet = bytearray()
@ -226,135 +219,116 @@ def boot(address):
packet.append((address >> 8) & 0xff)
packet.append(address & 0xff)
packet.append(packet_checksum(packet))
if not send_data(packet):
if not send_data(port, packet):
return False
return True
"""
def enter_dfu(portname):
p = serial.Serial(portname, 38400, timeout=2, parity=serial.PARITY_NONE, stopbits=1)
if not p.is_open:
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
p.write('dfu\r\n')
time.sleep(1)
s = p.readline()
p.close()
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)
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():
print "Bootloader is present"
if do_handshake(port):
#print("Bootloader is present")
bl_present = True
break
else:
print "No response from bootloader"
pass
#print("No response from bootloader")
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:
configure_commands(data[2:])
else:
print "Failed to configure command table"
sys.exit(1)
#print("Failed to configure command table")
error = "Failed to configure command table"
port.close()
return False
startpage = (address - FLASH_BASE)/PAGE_SIZE
numpages = st.st_size / PAGE_SIZE
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(startpage, numpages)
r = send_erase_cmd(port, startpage, numpages)
else:
r = send_ext_erase_cmd(startpage, numpages)
r = send_ext_erase_cmd(port, startpage, numpages)
if r == False:
print "Failed to erase pages"
#print("Failed to erase pages")
pass
else:
print "Erased {0} flash pages".format(numpages)
#print("Erased {0} flash pages".format(numpages))
pass
addr = address
first_chunk = None
with open(sys.argv[2], "rb") as f:
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 addr == address:
# Preserve the first chunk and write it last.
# This makes FW update as close to atomic as possible.
first_chunk = chunk
else:
rem = len(chunk) % 4
for i in range(rem):
chunk += 0xff
if not write_chunk(addr, chunk):
print "Write failed"
sys.exit(1)
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(100*(addr-address)/st.st_size))
sys.stdout.flush()
#sys.stdout.write("Flashing: {0:3d}%\r".format(int(100*(addr-address)/st.st_size)))
#sys.stdout.flush()
if write_chunk(address, first_chunk):
sys.stdout.write("\r\nFlashed boot sector at address 0x{:08x}\r\n".format(address))
sys.stdout.flush()
else:
print "Failed to write boot sector!!!"
sys.exit(1)
print
#print()
if not boot(port, address):
error = "Failed to send GO command"
port.close()
return False
port.close()
return True
if not boot(address):
print "Failed to send GO command"
if __name__ == '__main__':
if len(sys.argv) < 3:
print("Usage: {0} port image".format(sys.argv[0]))
sys.exit(1)
print "Booted"
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])

View File

@ -17,11 +17,13 @@ static StaticTimer_t static_timer;
#define RD_BUF_SIZE (BUF_SIZE)
uint8_t dtmp[RD_BUF_SIZE];
#define GPIO_UART1_RX GPIO_NUM_25
#define GPIO_UART1_TX GPIO_NUM_26
#define GPIO_TX_BUTTON GPIO_NUM_34
#define GPIO_RED_LED GPIO_NUM_5
#define GPIO_GREEN_LED GPIO_NUM_4
#define GPIO_UART1_RX GPIO_NUM_25
#define GPIO_UART1_TX GPIO_NUM_26
#define GPIO_TX_BUTTON GPIO_NUM_34
#define GPIO_RED_LED GPIO_NUM_5
#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)
{
@ -54,7 +56,7 @@ void bsp_uart_init()
uart_driver_install(UART_NUM_1, BUF_SIZE*2, 0, 0, NULL, 0);
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)
@ -109,12 +111,20 @@ void bsp_hw_init()
{
bsp_uart_init();
config_gpio(GPIO_TX_BUTTON, GPIO_MODE_INPUT, false, false);
gpio_set_direction(GPIO_TX_BUTTON, GPIO_MODE_INPUT);
gpio_set_intr_type(GPIO_TX_BUTTON, GPIO_INTR_NEGEDGE);
//config_gpio(GPIO_TX_BUTTON, GPIO_MODE_INPUT, false, false);
//gpio_set_direction(GPIO_TX_BUTTON, GPIO_MODE_INPUT);
//gpio_set_intr_type(GPIO_TX_BUTTON, GPIO_INTR_NEGEDGE);
config_gpio(GPIO_RED_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
gpio_set_direction(GPIO_RED_LED, GPIO_MODE_OUTPUT);
@ -124,8 +134,8 @@ void bsp_hw_init()
gpio_set_level(GPIO_GREEN_LED, 1);
#endif
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_TX_BUTTON, btn_isr, NULL);
//gpio_install_isr_service(0);
//gpio_isr_handler_add(GPIO_TX_BUTTON, btn_isr, NULL);
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);
__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()

View File

@ -5,4 +5,5 @@ otadata, data, ota, , 8K
phy_init, data, phy, , 4K
factory, app, factory, , 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