1 /*
2 * Copyright (c) 2022 HPMicro
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 <hpm_clock_drv.h>
17 #include <stdio.h>
18 #include <los_interrupt.h>
19 #include "hpm_littlefs_drv.h"
20 #include "hpm_csr_regs.h"
21 #include "hpm_l1c_drv.h"
22
23 extern struct HpmLittlefsCfg g_hpmLittlefsCfgs[];
24
25 xpi_nor_config_t *qiang_debug = NULL;
26
HpmLittlefsRead(int partition,UINT32 * offset,void * buf,UINT32 size)27 int HpmLittlefsRead(int partition, UINT32 *offset, void *buf, UINT32 size)
28 {
29 struct HpmLittleCtx *ctx = &g_hpmLittlefsCfgs[partition].ctx;
30 XPI_Type *base = (XPI_Type *)ctx->base;
31 uint32_t chipOffset = *offset;
32
33 uint32_t intSave = LOS_IntLock();
34 qiang_debug = &(ctx->xpiNorConfig);
35 hpm_stat_t status = rom_xpi_nor_read(base, xpi_xfer_channel_auto,
36 &ctx->xpiNorConfig, (uint32_t *)buf, chipOffset, size);
37 __asm volatile("fence.i");
38 LOS_IntRestore(intSave);
39 if (status != status_success) {
40 printf("[%s]: read addr: %u, size: %u status: %d failed!!!\n", ctx->mountPoint, chipOffset, size,status);
41 return -1;
42 }
43 return 0;
44 }
45
46
HpmLittlefsProg(int partition,UINT32 * offset,const void * buf,UINT32 size)47 int HpmLittlefsProg(int partition, UINT32 *offset, const void *buf, UINT32 size)
48 {
49 struct HpmLittleCtx *ctx = &g_hpmLittlefsCfgs[partition].ctx;
50 XPI_Type *base = (XPI_Type *)ctx->base;
51 uint32_t chipOffset = *offset;
52
53 uint32_t intSave = LOS_IntLock();
54 hpm_stat_t status = rom_xpi_nor_program(base, xpi_xfer_channel_auto,
55 &ctx->xpiNorConfig, (const uint32_t *)buf, chipOffset, size);
56
57 __asm volatile("fence.i"); /* mandatory, very important!!! */
58 LOS_IntRestore(intSave);
59
60 if (status != status_success) {
61 printf("[%s]: program addr: %u, size: %u failed!!!\n", ctx->mountPoint, chipOffset, size);
62 return -1;
63 }
64 return 0;
65 }
66
HpmLittlefsErase(int partition,UINT32 offset,UINT32 size)67 int HpmLittlefsErase(int partition, UINT32 offset, UINT32 size)
68 {
69 struct HpmLittleCtx *ctx = &g_hpmLittlefsCfgs[partition].ctx;
70 XPI_Type *base = (XPI_Type *)ctx->base;
71 uint32_t chipOffset = offset;
72
73 uint32_t intSave = LOS_IntLock();
74 hpm_stat_t status = rom_xpi_nor_erase_sector(base, xpi_xfer_channel_auto, &ctx->xpiNorConfig, chipOffset);
75 __asm volatile("fence.i"); /* mandatory, very important!!! */
76 LOS_IntRestore(intSave);
77 if (status != status_success) {
78 printf("[%s]: erase addr: %u, size: %u failed!!!\n", ctx->mountPoint, chipOffset, size);
79 return -1;
80 }
81
82 return 0;
83 }
84
85
86 #define HPMICRO_FLASH_SELFTEST_ENABLE 0
87
88 #if HPMICRO_FLASH_SELFTEST_ENABLE == 1
89
90 static uint8_t rbuf[4096];
91 static uint8_t wbuf[4096];
92
SelfTest(struct HpmLittlefsCfg * lfsPart)93 static void SelfTest(struct HpmLittlefsCfg *lfsPart)
94 {
95 struct HpmLittleCtx *ctx = &lfsPart->ctx;
96 struct PartitionCfg *cfg = &lfsPart->cfg;
97
98 printf("[%s]: Self Test Start\n", ctx->mountPoint);
99
100 uint32_t block = 0;
101 uint32_t start = 0;
102 uint32_t testSize = (cfg->blockSize > sizeof(wbuf)) ? sizeof(wbuf) : cfg->blockSize;
103 printf("[%s]: Self Test testSize: %u\n", ctx->mountPoint, testSize);
104
105 for (int i = 0; i < testSize; i++) {
106 wbuf[i] = i & 0xff;
107 }
108
109 uint32_t rsetp = 1024;
110 uint32_t wsetp = 1024;
111
112 for (block = 0; block < cfg->blockCount; block++) {
113 HpmLittlefsErase(cfg->partNo, ctx->startOffset + block * cfg->blockSize, cfg->blockSize);
114 printf("Erase OK\n");
115 uint32_t offset;
116 for (start = 0; start < testSize; start += wsetp) {
117 offset = ctx->startOffset + block * cfg->blockSize + start;
118 HpmLittlefsProg(cfg->partNo, (UINT32 *)&offset, (const void *)(wbuf + start), wsetp);
119 }
120 printf("Program OK\n");
121
122 for (start = 0; start < testSize; start += rsetp) {
123 offset = ctx->startOffset + block * cfg->blockSize + start;
124 HpmLittlefsRead(cfg->partNo, (UINT32 *)&offset, (void *)(rbuf + start), rsetp);
125 }
126 printf("Read OK\n");
127
128 for (int i = 0; i < testSize; i++) {
129 if (wbuf[i] != rbuf[i]) {
130 printf("%d: wbuf(%u) != rbuf(%u)\n", i, wbuf[i], rbuf[i]);
131 }
132 }
133
134 int isEqu = memcmp(wbuf, rbuf, testSize);
135 if (isEqu) {
136 printf("[%s]: block: %u fail\n", ctx->mountPoint, block);
137 break;
138 } else {
139 printf("[%s]: block: %u pass\n", ctx->mountPoint, block);
140 }
141 }
142 }
143 #endif
144
HpmLittlefsDriverInit(struct HpmLittlefsCfg * lfsPart)145 int HpmLittlefsDriverInit(struct HpmLittlefsCfg *lfsPart)
146 {
147 struct HpmLittleCtx *ctx = &lfsPart->ctx;
148 struct PartitionCfg *cfg = &lfsPart->cfg;
149 XPI_Type *base = (XPI_Type *)ctx->base;
150
151 if (ctx->isInited) {
152 return 0;
153 }
154 ctx->isInited = 1;
155
156 printf("hpm lfs: mountPoint: %s\n", ctx->mountPoint);
157 printf("hpm lfs: startOffset: %u\n", ctx->startOffset);
158 printf("hpm lfs: len: %u\n", ctx->len);
159
160 xpi_nor_config_option_t option;
161 option.header.U = 0xfcf90001U;
162 option.option0.U = 0x00000005U;
163 option.option1.U = 0x00001000U;
164 uint32_t blockSize;
165 uint32_t blockCount;
166 uint32_t intSave = LOS_IntLock();
167 hpm_stat_t status = rom_xpi_nor_auto_config(base, &ctx->xpiNorConfig, &option);
168 rom_xpi_nor_get_property(base, &ctx->xpiNorConfig, xpi_nor_property_sector_size, &blockSize);
169 __asm volatile("fence.i");
170 LOS_IntRestore(intSave);
171 if (status != status_success) {
172 printf("Error: rom_xpi_nor_auto_config\n");
173 while (1);
174 }
175
176 blockCount = ctx->len / blockSize;
177 printf("hpm lfs: blockCount: %u\n", blockCount);
178 printf("hpm lfs: blockSize: %u\n", blockSize);
179 printf("------------------------------------------\n");
180
181 cfg->blockSize = blockSize;
182 cfg->blockCount = blockCount;
183 #if HPMICRO_FLASH_SELFTEST_ENABLE == 1
184 SelfTest(lfsPart);
185 #endif
186
187 return 0;
188 }
189
190
191