mirror of
https://github.com/peterantypas/maiana.git
synced 2025-06-01 15:20:40 -07:00
Checkpoint
This commit is contained in:
parent
2df4e596e2
commit
d820455b4a
@ -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])
|
||||
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
|
Loading…
x
Reference in New Issue
Block a user