#ifndef _RTL8710_FLASHER_H_ #define _RTL8710_FLASHER_H_ #include #include #define __always_long_call __attribute__((long_call)) #define __packed __attribute__((packed)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define BIT(x) (1 << (x)) #define READ_CHUNK_SIZE 4 #define FLASH_WORD_SIZE 4 #define VERIFY_CHUNK_SIZE 4 #define VERIFY_WORDS (VERIFY_CHUNK_SIZE / FLASH_WORD_SIZE) #define WRITE_CHUNK_SIZE 256 #define SPI_FLASH_BASE 0x08000000 #define PERI_ON_BASE 0x40000200 #define PERI_ON_SOC_FUNC_EN (*(volatile uint32_t *)(PERI_ON_BASE + 0x10)) #define FLASH_PERIPH_BIT BIT(4) #define FLASH_CLOCK_BIT BIT(8) /* Flash control structure */ typedef struct __packed { volatile uint32_t start; /* 0x00: Control register */ volatile uint32_t cmd; /* 0x04: Command register */ volatile uint32_t status; /* 0x08: Status register */ volatile uint32_t param; /* 0x0C: Parameter/ID register */ volatile uint32_t offset; /* 0x10: Flash offset */ volatile uint32_t len; /* 0x14: Length field */ volatile uint32_t reserved; /* 0x18: Padding to maintain 0x20 data offset */ volatile uint32_t reserved2; /* 0x1C: Padding to maintain 0x20 data offset */ volatile uint8_t data[]; /* 0x20: Data buffer */ } flash_control_t; #define FLASH_CONTROL ((flash_control_t *)BUFFER_ADDRESS) /* Flash commands */ typedef enum { CMD_READ_ID = 0, /* Read Flash ID and capacity */ CMD_MASS_ERASE = 1, /* Erase entire flash */ CMD_SECTOR_ERASE = 2, /* Erase 4KB sector at offset */ CMD_READ = 3, /* Read data into buffer */ CMD_WRITE = 4, /* Write buffer to flash */ CMD_VERIFY = 5, /* Verify buffer against flash */ CMD_MAX = 6 /* For bounds checking */ } flash_command_t; typedef struct { /* Device identification */ uint32_t vendor_id; /* Flash vendor ID = 5 */ /* Operating mode configuration */ uint8_t current_mode; /* Current SPI mode (0=single, 1=dual, 2=quad) = 1 */ uint8_t clock_div; /* SPI clock divider (spi_clk = oc_clk/(2*div)) = 1 */ uint8_t boot_clock_div; /* Boot-time SPI clock divider = 4 */ uint32_t current_read_cmd; /* Active read command = 3 */ /* Status register bits */ uint32_t quad_enable_bit; /* Status bit for quad mode = 512 */ uint32_t busy_bit; /* Write-in-progress status bit = 1 */ uint32_t write_enable_bit; /* Write enable latch bit = 2 */ uint32_t has_status2_reg; /* Whether status register 2 exists = 1 */ /* Timing configuration */ uint8_t read_sample_delay; /* Read sampling delay = 1 */ uint8_t read_dummy_cycles[3]; /* Dummy cycles for different modes = {0,4,6} */ /* Read commands */ uint32_t read_dual_out; /* Dual output read = 0x3B */ uint32_t read_dual_io; /* Dual I/O read = 0xBB */ uint32_t read_quad_out; /* Quad output read = 0x6B */ uint32_t read_quad_io; /* Quad I/O read = 0xEB */ /* Write commands */ uint32_t write_dual_data; /* Dual data write = 0 */ uint32_t write_dual_addr; /* Dual address/data write = 0 */ uint32_t write_quad_data; /* Quad data write = 0 */ uint32_t write_quad_addr; /* Quad address/data write = 32 */ /* Valid command masks */ uint32_t dual_mode_commands; /* Valid commands in dual mode = 516 */ uint32_t quad_mode_commands; /* Valid commands in quad mode = 784 */ /* Basic flash commands */ uint8_t cmd_write_enable; /* Write enable = 0x06 */ uint8_t cmd_read_id; /* Read identification = 0x9F */ uint8_t cmd_read_status; /* Read status register = 0x05 */ uint8_t cmd_read_status2; /* Read status register 2 = 0x35 */ uint8_t cmd_write_status; /* Write status register = 0x01 */ uint8_t cmd_write_status2; /* Write status register 2 = 0x00 */ /* Erase commands */ uint8_t cmd_erase_chip; /* Chip erase = 0x60 */ uint8_t cmd_erase_block; /* 64KB block erase = 0xD8 */ uint8_t cmd_erase_sector; /* 4KB sector erase = 0x20 */ /* Power management */ uint8_t cmd_release_powerdown; /* Exit power down = 0xAB */ uint8_t cmd_enter_powerdown; /* Enter power down = 0xB9 */ /* Debug */ uint8_t debug_enable; /* Enable debug output = 0 */ uint8_t phase_shift_idx; /* Phase shift calibration index = 0 */ } FLASH_InitTypeDef; /* external ROM bloat */ extern FLASH_InitTypeDef flash_init_para; extern __always_long_call uint32_t DiagPrintf(const char *fmt, ...); __always_long_call void RCC_PeriphClockCmd(uint32_t APBPeriph, uint32_t APBPeriph_Clock, uint8_t NewState); __always_long_call void PINMUX_Ctrl(uint32_t Function, uint32_t PinLocation, bool Operation); __always_long_call void FLASH_Erase(uint32_t EraseType, uint32_t Address); __always_long_call void FLASH_SetStatusBits(uint32_t SetBits, uint32_t NewState); // __always_long_call void FLASH_WriteEn(void); __always_long_call void FLASH_RxCmd(uint8_t cmd, uint32_t read_len, uint8_t *read_data); __always_long_call void FLASH_TxData12B(uint32_t StartAddr, uint8_t DataPhaseLen, uint8_t *pData); __always_long_call void FLASH_StructInit_GD(void *FLASH_InitStruct); __always_long_call uint8_t FLASH_Init(uint8_t SpicBitMode); __always_long_call uint32_t FLASH_ClockDiv(uint8_t Div); #endif // _RTL8710_FLASHER_H_