UU-01-spi_nor_flash 研究1
COBJS-$(CONFIG_HISFC_FLASH_GODNET) +=
hisfc300new_spi_ids.o
hisfc300new.o
hisfc300new_godnet.o
COBJS-y =
spi_compatible.o
spi_ids.o
- *hifmc_spi_nor_probe* 这个函数很重要
参数类型是 `struct spi_flash`,`struct hisfmc_spi`,`hifmc100_read_ids()`通过给CPU芯片寄存器发一系列命令来获得ids;
然后通过`hisfm_spi_nor_serach_ids(ids)` 查表获得对此flash的一系列操作行为
- `struct spi_flash *spi_nor_flash` `struct spi_nor_info` 这两个才是描述的flash对象和现实中最接近,
里面包含了对flash的名称,大小,读写擦除操作
**spi_flash.h**
```c++
/*spi_flash.h */
struct spi_flash {
struct spi_slave *spi;
const char *name;
u32 size;
int (*read) (struct spi_flash *flash, u32 offset,size_t len,void *buf);
int (*write)(struct spi_flash *flash, u32 offset,size_t len,const void *buf);
int (*erase)(struct spi_flash *flash, u32 offset,size_t len);
}
/* struct hisfc_host */
struct hisfc_host{
struct spi_flash spiflash[1];
void *iobase;
void *regbase;
void *lock;
void *cfgreg;
unsigned int erasesize;
void (*set_system_clock)(struct hisfc_host *host,
struct spi_operation *op,int clk_en);
void (*set_host_addr_mode)(struct hisfc_host *host,int enable)
int num_chip;
struct hisfc_spi spi[CONFIG_HISFC300_CHIP_NUM+1];
};
struct mtd_info_ex {
};
struct spi_info {
char *name;
unsigned char id[8];
unsigened int id_len;
unsigned long chipsize;
unsigend int erasesize;
unsigned int addrcycle;
#define MAX_SPI_OP (8)
struct spi_operation *read[8];
struct spi_operation *write[8];
struct spi_operation *erase[8];
};
struct spi_tag {
char name[16];
unsigned char id[8];
unsigned int id_len;
unsigned long chipsize;
unsigned long erasesize;
unsigned long addrcycle; // 不是特别清楚
#define MAX_SPI_OP_T (8)
struct spi_operation_t read[MAX_SPI_OP_T];
struct spi_operation_t write[MAX_SPI_OP_T];
struct spi_operation_t erase[MAX_SPI_OP_T];
}
struct hisfc_spi {
char *name;
int chipselect;
unsigned long long chipsize;
unsigned int erasesize;
void *iobase;
unsigned int addrcycle;
struct spi_operation read[1];
struct spi_operation write[1];
struct spi_operation erase[MAX_SPI_OP];
void *host;
struct spi_driver *driver;
};
struct spi_driver {
int (*wait_ready)(struct hisfc_spi *spi);
int (*write_enable)(struct hisfc_spi *spi);
int (*entry_4addr)(struct hisfc_spi *spi, int enable);
int (*bus_prepare)(struct hisfc_spi *spi, int op);
int (*qe_enable)(struct hisfc_spi *spi);
};
struct mtd_info_ex{u_char type; /* chip type MTD_NORFLASH / MTD_NANDFLASH */uint64_t chipsize; /* total size of the nand/spi chip */u_int32_t erasesize;u_int32_t pagesize;u_int32_t numchips; /* number of nand chips */u_int32_t oobsize;u_int32_t addrcycle;u_int32_t ecctype;u_char ids[8];u_int32_t id_length;char name[16]; /* chip names */int hostver; /* host controller version */};struct hifmc_host {struct spi_flash spi_nor_flash[1];struct mtd_info_ex *spi_nor_info; // mtd_info_ex主要体现的是flash信息struct hifmc_spi spi[CONFIG_SPI_NOR_MAX_CHIP_NUM];void *regbase;void *iobase;/* This is maybe an un-aligment address, only for malloc or free */char *buforg;char *buffer;unsigned int dma_buffer;void (*set_system_clock)(struct spi_op *op, int clk_en);void (*set_host_addr_mode)(struct hifmc_host *host, int enable);#ifdef CONFIG_CMD_SPI_BLOCK_PROTECTIONunsigned int start_addr;unsigned int end_addr;unsigned char cmp;unsigned char level;#endif};
```
regbase:SFC_REG_BASE 0x1001_0000
spi nor flash 寄存器地址映射空间首地址
iobase: SFC_MEM_BASE 0x5800_0000 0x5B00_0000 64MB
spi flash 存储空间地址映射地址
cfgreg: CRG_REG_BASE CRG 寄存器地址 0x2003_0000
关于时钟的
<span style="font-family: courier;">
##hisfc300_init(void)::
</span>
hisfc300_init(void):
> - struct hisfc_host 对象初始化
> - check flash版本寄存器
> - hisfc300_probe
> - hisfc300_set_system_clock: 确实是设置时钟寄存器PERI_CRG48(24MHz,enable clk,复位禁止)
> - 设置0x1001_0110 Timing配置寄存器:片选的setup time,片选的hold time
> - hisfc300_spi_probe(host)
> - struct spi_flash的方法赋值
> - probe_spi_size()
spiinfo = spi_serach_ids(hisfc300new_spi_info_table, ids);
> 主要:依据id从表格中匹配flash,从而获取此flash的**详细**信息,然后就是结构体赋值spi_info ->spi_tag,这两个结构体基本一致,只是稍有不同