Files
templates/c/rs485-boot/include/rs485_boot.h

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