#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);
