1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cfiflash_internal.h"
17
18 #if (LOSCFG_SUPPORT_FATFS == 1)
DiskInit(BYTE pdrv)19 static DSTATUS DiskInit(BYTE pdrv)
20 {
21 if (CfiFlashQuery(pdrv)) {
22 return RES_ERROR;
23 }
24
25 g_diskDrv.initialized[pdrv] = 1;
26 return RES_OK;
27 }
28
DiskStatus(BYTE pdrv)29 static DSTATUS DiskStatus(BYTE pdrv)
30 {
31 if (g_diskDrv.initialized[pdrv] != 1) {
32 return RES_ERROR;
33 }
34
35 return RES_OK;
36 }
37
DisckRead(BYTE pdrv,BYTE * buffer,DWORD startSector,UINT nSectors)38 static DSTATUS DisckRead(BYTE pdrv, BYTE *buffer, DWORD startSector, UINT nSectors)
39 {
40 unsigned int bytes = CfiFlashSec2Bytes(nSectors);
41 unsigned int byteOffset = CfiFlashSec2Bytes(startSector);
42
43 uint32_t *p = (uint32_t *)buffer;
44 return CfiFlashRead(pdrv, p, byteOffset, bytes);
45 }
46
DiskWrite(BYTE pdrv,const BYTE * buffer,DWORD startSector,UINT nSectors)47 static DSTATUS DiskWrite(BYTE pdrv, const BYTE *buffer, DWORD startSector, UINT nSectors)
48 {
49 unsigned int bytes = CfiFlashSec2Bytes(nSectors);
50 unsigned int byteOffset = CfiFlashSec2Bytes(startSector);
51
52 uint32_t *p = (uint32_t *)buffer;
53 return CfiFlashWrite(pdrv, p, byteOffset, bytes);
54 }
55
DiskIoctl(BYTE pdrv,BYTE cmd,void * buff)56 static DSTATUS DiskIoctl(BYTE pdrv, BYTE cmd, void *buff)
57 {
58 if (g_diskDrv.initialized[pdrv] != 1) {
59 return RES_ERROR;
60 }
61
62 switch (cmd) {
63 case CTRL_SYNC:
64 break;
65 case GET_SECTOR_COUNT:
66 *(DWORD *)buff = CFIFLASH_SECTORS;
67 break;
68 case GET_SECTOR_SIZE:
69 *(WORD *)buff = CFIFLASH_SEC_SIZE;
70 break;
71 case GET_BLOCK_SIZE:
72 *(WORD *)buff = CFIFLASH_EXPECT_ERASE_REGION;
73 break;
74 default:
75 return RES_PARERR;
76 }
77
78 return RES_OK;
79 }
80
81 static DiskioDrvTypeDef g_cfiBlkops = {
82 DiskInit,
83 DiskStatus,
84 DisckRead,
85 DiskWrite,
86 DiskIoctl,
87 };
88
GetCfiBlkOps(void)89 DiskioDrvTypeDef *GetCfiBlkOps(void)
90 {
91 return &g_cfiBlkops;
92 }
93 #endif /* LOSCFG_SUPPORT_FATFS == 1 */
94
95 #if (LOSCFG_SUPPORT_LITTLEFS == 1)
96 static uint32_t g_flashDevId = 1;
97
98 #define READ_SIZE 256
99 #define PROG_SIZE 256
100 #define BLOCK_SIZE CFIFLASH_ERASEBLK_SIZE
101 #define BLOCK_COUNT CFIFLASH_EXPECT_BLOCKS + 1
102 #define CACHE_SIZE 256
103 #define LOOKAHEAD_SIZE 16
104 #define BLOCK_CYCLES 1000
105
LittlefsRead(const struct lfs_config * cfg,lfs_block_t block,lfs_off_t off,void * buffer,lfs_size_t size)106 static int LittlefsRead(const struct lfs_config *cfg, lfs_block_t block,
107 lfs_off_t off, void *buffer, lfs_size_t size)
108 {
109 uint32_t addr = cfg->block_size * block + off;
110 uint32_t devid = *((uint32_t *)cfg->context);
111
112 uint32_t *p = (uint32_t *)buffer;
113 return CfiFlashRead(devid, p, addr, size);
114 }
115
LittlefsProg(const struct lfs_config * cfg,lfs_block_t block,lfs_off_t off,const void * buffer,lfs_size_t size)116 static int LittlefsProg(const struct lfs_config *cfg, lfs_block_t block,
117 lfs_off_t off, const void *buffer, lfs_size_t size)
118 {
119 uint32_t addr = cfg->block_size * block + off;
120 uint32_t devid = *((uint32_t *)cfg->context);
121
122 uint32_t *p = (uint32_t *)buffer;
123 return CfiFlashWrite(devid, p, addr, size);
124 }
125
LittlefsErase(const struct lfs_config * cfg,lfs_block_t block)126 static int LittlefsErase(const struct lfs_config *cfg, lfs_block_t block)
127 {
128 uint32_t addr = cfg->block_size * block;
129 uint32_t devid = *((uint32_t *)cfg->context);
130 return CfiFlashErase(devid, addr);
131 }
132
LittlefsSync(const struct lfs_config * cfg)133 static int LittlefsSync(const struct lfs_config *cfg)
134 {
135 return LFS_ERR_OK;
136 }
137
138 static struct lfs_config g_lfsConfig = {
139 // block device operations
140 .context = &g_flashDevId,
141 .read = LittlefsRead,
142 .prog = LittlefsProg,
143 .erase = LittlefsErase,
144 .sync = LittlefsSync,
145
146 // block device configuration
147 .read_size = READ_SIZE,
148 .prog_size = PROG_SIZE,
149 .block_size = BLOCK_SIZE,
150 .block_count = BLOCK_COUNT,
151 .cache_size = CACHE_SIZE,
152 .lookahead_size = LOOKAHEAD_SIZE,
153 .block_cycles = BLOCK_CYCLES,
154 .read_buffer = NULL,
155 .prog_buffer = NULL,
156 .lookahead_buffer = NULL
157 };
158
LittlefsDriverInit(void)159 int LittlefsDriverInit(void)
160 {
161 uint32_t devid = *((uint32_t *)g_lfsConfig.context);
162 return CfiFlashQuery(devid);
163 }
164
GetCfiLfsCfg(void)165 struct lfs_config* GetCfiLfsCfg(void)
166 {
167 return &g_lfsConfig;
168 }
169 #endif /* LOSCFG_SUPPORT_LITTLEFS == 1 */
170