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