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_PROTECTION
unsigned 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,这两个结构体基本一致,只是稍有不同

























    

















原文链接: https://www.cnblogs.com/xiaoweishine/p/4839353.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    UU-01-spi_nor_flash 研究1

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/222305

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 上午11:41
下一篇 2023年2月13日 上午11:41

相关推荐