summaryrefslogtreecommitdiff
path: root/bsp/nuvoton/libraries/nu_packages/SPINAND/spinand.h
blob: 737ccec273e1f694d40ae667af2bb1526797a3bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**************************************************************************//**
*
* @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date            Author       Notes
* 2021-1-13       Wayne        First version
*
******************************************************************************/

#ifndef __SPINAND_H__
#define __SPINAND_H__

#include <rtthread.h>

#include <drivers/mtd_nand.h>
#include "drv_spi.h"
#include <board.h>

struct spinand_ops
{
    rt_err_t (*block_erase)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
    uint8_t (*block_isbad)(struct rt_qspi_device *qspi, uint32_t u32PageAddr);
    rt_err_t (*block_markbad)(struct rt_qspi_device *qspi,  uint32_t u32PageAddr);
    rt_err_t (*die_select)(struct rt_qspi_device *qspi, uint8_t select_die);
    rt_err_t (*jedecid_get)(struct rt_qspi_device *qspi, uint32_t *pu32ID);
    rt_err_t (*program_dataload)(struct rt_qspi_device *qspi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8DataBuff,
                                 uint32_t u32DataCount, uint8_t *pu8SpareBuff, uint32_t u32SpareCount);

    rt_err_t (*program_execute)(struct rt_qspi_device *qspi,  uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
    rt_err_t (*read_dataload)(struct rt_qspi_device *qspi, uint8_t u8Addr2, uint8_t u8Addr1, uint8_t u8Addr0);
    rt_err_t (*read_quadoutput)(struct rt_qspi_device *qspi, uint8_t u8AddrH, uint8_t u8AddrL, uint8_t *pu8DataBuff, uint32_t u32DataCount);
};
typedef struct spinand_ops *nu_spinand_ops_t;

#define SPINAND_FLASH_JEDECID              g_spinandflash_dev.info.u32JEDECID
#define SPINAND_FLASH_PAGE_SIZE            g_spinandflash_dev.info.u16PageSize
#define SPINAND_FLASH_OOB_SIZE             g_spinandflash_dev.info.u16OOBSize
#define SPINAND_FLASH_QUADREAD_CMDID       g_spinandflash_dev.info.u8QuadReadCmdId
#define SPINAND_FLASH_DUMMYBYTE            g_spinandflash_dev.info.u8DummyByte
#define SPINAND_FLASH_BLOCK_NUM            g_spinandflash_dev.info.u32BlockPerFlash
#define SPINAND_FLASH_PAGE_PER_BLOCK_NUM   g_spinandflash_dev.info.u32PagePerBlock
#define SPINAND_FLASH_DESCRIPTION          g_spinandflash_dev.info.szDescription
#define SPINAND_FLASH_MCP                  g_spinandflash_dev.info.u8IsDieSelect

#define SPINAND_FLASH_INFO                 &g_spinandflash_dev.info
#define SPINAND_FLASH_QSPI                 g_spinandflash_dev.qspi_device
#define SPINAND_FLASH_LOCK                 &g_spinandflash_dev.lock
#define SPINAND_FLASH_OPS                  g_spinandflash_dev.ops

#define SPINAND_DIE_ID0 (0)
#define SPINAND_DIE_ID1 (1)

#define SPINAND_SPARE_LAYOUT_SIZE          16

/* SPI NAND flash information */
struct nu_spinand_info
{
    uint32_t   u32JEDECID;
    uint16_t   u16PageSize;
    uint16_t   u16OOBSize;
    uint8_t    u8QuadReadCmdId;
    uint8_t    u8ReadStatusCmdId;
    uint8_t    u8WriteStatusCmdid;
    uint8_t    u8StatusValue;
    uint8_t    u8DummyByte;
    uint32_t   u32BlockPerFlash;
    uint32_t   u32PagePerBlock;
    uint8_t    u8IsDieSelect;
    const char *szDescription;

    uint8_t    au8DataLayout[SPINAND_SPARE_LAYOUT_SIZE];
    uint8_t    au8EccLayout[SPINAND_SPARE_LAYOUT_SIZE];
};
typedef struct nu_spinand_info *nu_spinand_info_t;

struct nu_spinand
{
    struct nu_spinand_info info;
    struct rt_qspi_device *qspi_device;
    nu_spinand_ops_t       ops;
    struct rt_mutex        lock;
};
typedef struct nu_spinand *nu_spinand_t;

rt_err_t rt_hw_mtd_spinand_register(const char *device_name);
rt_size_t nu_qspi_transfer_message(struct rt_qspi_device  *device, struct rt_qspi_message *message);
rt_err_t nu_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length);
rt_err_t nu_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length);
rt_err_t spinand_flash_init(struct rt_qspi_device *qspi);
rt_err_t spinand_jedecid_get(struct rt_qspi_device *qspi, uint32_t *pu32ID);
int spinand_supported_flash_size(void);
nu_spinand_info_t spinand_info_get(int idx);

extern struct nu_spinand g_spinandflash_dev;
extern rt_uint8_t spinand_flash_data_layout[SPINAND_SPARE_LAYOUT_SIZE];
extern rt_uint8_t spinand_flash_ecc_layout[SPINAND_SPARE_LAYOUT_SIZE];

#endif /* __SPINAND_H__ */