132 lines
5.2 KiB
C
132 lines
5.2 KiB
C
#ifndef _RTL8710_FLASHER_H_
|
|
#define _RTL8710_FLASHER_H_
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#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 32
|
|
#define VERIFY_CHUNK_SIZE 32
|
|
#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_ */ |