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