74 lines
2.1 KiB
C
74 lines
2.1 KiB
C
#ifndef RS485_BOOT_H
|
|
#define RS485_BOOT_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define RS485_BOOT_VERSION 1U
|
|
#define RS485_BOOT_MAX_PAYLOAD 512U
|
|
#define RS485_BOOT_MAX_FRAME (8U + RS485_BOOT_MAX_PAYLOAD + 4U)
|
|
#define RS485_BOOT_DATA_HEADER_SIZE 8U
|
|
#define RS485_BOOT_MAX_BLOCK (RS485_BOOT_MAX_PAYLOAD - RS485_BOOT_DATA_HEADER_SIZE)
|
|
|
|
typedef enum {
|
|
RS485_BOOT_IDLE = 0U,
|
|
RS485_BOOT_RECEIVING = 1U,
|
|
RS485_BOOT_READY = 2U,
|
|
RS485_BOOT_FAILED = 3U
|
|
} rs485_boot_state_t;
|
|
|
|
typedef enum {
|
|
RS485_BOOT_OK = 0U,
|
|
RS485_BOOT_INVALID_ARGUMENT = 1U,
|
|
RS485_BOOT_INVALID_LENGTH = 2U,
|
|
RS485_BOOT_BUSY = 5U,
|
|
RS485_BOOT_INTERNAL = 7U,
|
|
RS485_BOOT_UNSUPPORTED = 0x11U
|
|
} rs485_boot_result_t;
|
|
|
|
typedef struct {
|
|
uint32_t app_address;
|
|
uint32_t app_size;
|
|
uint16_t max_block_size;
|
|
} rs485_boot_config_t;
|
|
|
|
typedef struct {
|
|
bool (*transmit)(void *user, const uint8_t *data, uint16_t length);
|
|
bool (*erase)(void *user, uint32_t image_size);
|
|
bool (*write)(void *user, uint32_t offset, const uint8_t *data, uint16_t length);
|
|
bool (*read)(void *user, uint32_t offset, uint8_t *data, uint16_t length);
|
|
bool (*image_valid)(void *user, uint32_t image_size, uint32_t image_crc32);
|
|
void (*reboot)(void *user);
|
|
} rs485_boot_port_t;
|
|
|
|
typedef struct {
|
|
rs485_boot_config_t config;
|
|
rs485_boot_port_t port;
|
|
void *port_user;
|
|
uint8_t parser[RS485_BOOT_MAX_FRAME];
|
|
uint16_t parser_length;
|
|
uint8_t tx[RS485_BOOT_MAX_FRAME];
|
|
uint8_t scratch[32];
|
|
uint32_t image_size;
|
|
uint32_t image_crc32;
|
|
uint32_t next_offset;
|
|
uint32_t crc_errors;
|
|
rs485_boot_state_t state;
|
|
} rs485_boot_t;
|
|
|
|
bool rs485_boot_init(rs485_boot_t *boot, const rs485_boot_config_t *config,
|
|
const rs485_boot_port_t *port, void *port_user);
|
|
void rs485_boot_feed(rs485_boot_t *boot, const uint8_t *data, size_t length);
|
|
void rs485_boot_abort(rs485_boot_t *boot);
|
|
uint32_t rs485_boot_crc32(const uint8_t *data, size_t length);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|