#pragma once
#include "port.h"
enum flags_t{
F_NO_ME = 1<<0, // Mass-Erase not supported
F_OBLL = 1<<1, // OBL_LAUNCH required
F_PEMPTY = 1<<2, // clear PEMPTY bit required
F_GEN = 1<<3, // No implicit "STM32" prefix for name
};
struct stm32_dev_t { // const device data
uint16_t id;
uint8_t fl_ppsh; // pages per sector shift
uint8_t flags;
const char *sname;
uint32_t ram_start, ram_end;
uint32_t fl_start, fl_end;
const char *fl_psh; // page shift value list
uint32_t opt_start, opt_end;
uint32_t mem_start, mem_end;
bool addr_in_ram(uint32_t a) const{return ram_start<=a && a<ram_end;}
bool addr_in_flash(uint32_t a, bool ceil=false) const{return fl_start<=a && (ceil?a<=fl_end:a<fl_end);}
bool addr_in_opt_bytes(uint32_t a) const{return opt_start<=a && a<=opt_end;} // here: last byte is inclusive
bool addr_in_sysmem(uint32_t a) const{return mem_start<=a && a<mem_end;}
int flash_addr_to_page(uint32_t addr, bool ceil=false) const;
uint32_t flash_page_to_addr(int page) const;
};
extern const stm32_dev_t devices[];
struct stm32 {
enum {
MAX_RX_FRAME = 256, /* cmd read memory */
MAX_TX_FRAME = 1+256+1, /* cmd write memory */
MAX_PAGES = 0x0000ffff,
MASS_ERASE = 0x00100000, /* > 2 x max_pages */
};
struct cmd_t {
uint8_t get,gvr,gid,rm,go,wm,er; /* this may be extended erase */
uint8_t wp,uw,rp,ur,crc;
cmd_t() {memset(this,0xFF,sizeof*this);}
};
enum err_t{
OK,
ERR_UNKNOWN, /* Generic error */
ERR_NACK,
ERR_NO_CMD, /* Command not available in bootloader */
};
Port&port;
uint8_t bl_version;
uint8_t version;
uint8_t option1, option2;
uint16_t pid;
cmd_t cmd;
const stm32_dev_t*dev;
stm32(Port&port, const char init);
~stm32();
err_t read_memory(uint32_t address, uint8_t data[], unsigned len) const;
err_t write_memory(uint32_t address, const uint8_t data[], unsigned len) const;
err_t wunprot_memory() const;
err_t wprot_memory() const;
err_t erase_memory(uint32_t spage, uint32_t pages) const;
err_t go(uint32_t address) const;
err_t reset_device() const;
err_t readprot_memory() const;
err_t runprot_memory() const;
err_t crc_memory(uint32_t address, uint32_t length, uint32_t&crc) const;
err_t crc_wrapper(uint32_t address, uint32_t length, uint32_t&crc) const;
static uint32_t sw_crc(uint32_t crc, const uint8_t*buf, unsigned len);
operator bool() const{return okay;} // check whether constructor ran successful
private:
bool okay;
err_t get_ack(unsigned ms=0) const;
err_t send_command(uint8_t cmd, unsigned ms=0)const;
err_t resync() const;
err_t guess_len_cmd(uint8_t cmd,uint8_t*data, unsigned len) const;
err_t send_init_seq() const;
err_t mass_erase() const;
err_t pages_erase(uint32_t spage, uint32_t pages) const;
err_t run_raw_code(uint32_t target_address, const uint8_t *code, uint32_t code_size) const;
err_t onecommand(const char*action,uint8_t cmd,unsigned ms,uint8_t stretchcmd) const;
};
#define le_u32(v) (v)
#include <stdio.h> //FILE
void printStatus(FILE *fd, int condition);
extern FILE *diag;
Detected encoding: UTF-8 | 0
|