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