• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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