Balance side (uart_ota.c): downloads io-firmware.bin from Gitea to RAM, computes SHA256, then streams to IO over UART1 (GPIO17/18, 460800 baud) as OTA_BEGIN/OTA_DATA/OTA_END frames with CRC8 + per-chunk ACK/retry (×3). IO side (uart_ota_recv.c): receives frames, writes to inactive OTA partition via esp_ota_write, verifies SHA256 on OTA_END, sets boot partition, reboots. IO board main.c + CMakeLists.txt scaffold included. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
65 lines
2.0 KiB
C
65 lines
2.0 KiB
C
#pragma once
|
|
/* uart_ota.h — UART OTA protocol for Balance→IO firmware update (bd-21hv)
|
|
*
|
|
* Balance downloads io-firmware.bin from Gitea, then streams it to the IO
|
|
* board over UART1 (GPIO17/18, 460800 baud) in 1 KB chunks with ACK.
|
|
*
|
|
* Protocol frame format (both directions):
|
|
* [TYPE:1][SEQ:2 BE][LEN:2 BE][PAYLOAD:LEN][CRC8:1]
|
|
* CRC8-SMBUS over TYPE+SEQ+LEN+PAYLOAD.
|
|
*
|
|
* Balance→IO:
|
|
* OTA_BEGIN (0xC0) payload: uint32 total_size BE + uint8[32] sha256
|
|
* OTA_DATA (0xC1) payload: uint8[] chunk (up to 1024 bytes)
|
|
* OTA_END (0xC2) no payload
|
|
* OTA_ABORT (0xC3) no payload
|
|
*
|
|
* IO→Balance:
|
|
* OTA_ACK (0xC4) payload: uint16 acked_seq BE
|
|
* OTA_NACK (0xC5) payload: uint16 failed_seq BE + uint8 err_code
|
|
* OTA_STATUS (0xC6) payload: uint8 state + uint8 progress%
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
/* UART for Balance→IO OTA */
|
|
#include "driver/uart.h"
|
|
#define UART_OTA_PORT UART_NUM_1
|
|
#define UART_OTA_BAUD 460800
|
|
#define UART_OTA_TX_GPIO 17
|
|
#define UART_OTA_RX_GPIO 18
|
|
|
|
#define OTA_UART_CHUNK_SIZE 1024
|
|
#define OTA_UART_ACK_TIMEOUT_MS 3000
|
|
#define OTA_UART_MAX_RETRIES 3
|
|
|
|
/* Frame type bytes */
|
|
#define UART_OTA_BEGIN 0xC0u
|
|
#define UART_OTA_DATA 0xC1u
|
|
#define UART_OTA_END 0xC2u
|
|
#define UART_OTA_ABORT 0xC3u
|
|
#define UART_OTA_ACK 0xC4u
|
|
#define UART_OTA_NACK 0xC5u
|
|
#define UART_OTA_STATUS 0xC6u
|
|
|
|
/* NACK error codes */
|
|
#define OTA_ERR_BAD_CRC 0x01u
|
|
#define OTA_ERR_WRITE 0x02u
|
|
#define OTA_ERR_SIZE 0x03u
|
|
|
|
typedef enum {
|
|
UART_OTA_S_IDLE = 0,
|
|
UART_OTA_S_DOWNLOADING, /* downloading from Gitea */
|
|
UART_OTA_S_SENDING, /* sending to IO board */
|
|
UART_OTA_S_DONE,
|
|
UART_OTA_S_FAILED,
|
|
} uart_ota_send_state_t;
|
|
|
|
extern volatile uart_ota_send_state_t g_uart_ota_state;
|
|
extern volatile uint8_t g_uart_ota_progress;
|
|
|
|
/* Trigger IO firmware update. Uses g_io_update (from gitea_ota).
|
|
* Downloads bin, then streams via UART. Returns false if busy or no update. */
|
|
bool uart_ota_trigger(void);
|