Skip to content

Commit 398f815

Browse files
committed
MXRT1050: Add support for Flash driver
Signed-off-by: Mahesh Mahadevan <[email protected]>
1 parent 02aeb57 commit 398f815

File tree

5 files changed

+539
-2
lines changed

5 files changed

+539
-2
lines changed
Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2019 ARM Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "flash_api.h"
19+
#include "mbed_toolchain.h"
20+
#include "mbed_critical.h"
21+
22+
#if DEVICE_FLASH
23+
24+
#include "fsl_flexspi.h"
25+
#include "fsl_cache.h"
26+
#include "flash_defines.h"
27+
28+
AT_QUICKACCESS_SECTION_CODE(void flexspi_update_lut_ram(void));
29+
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_write_enable_ram(uint32_t baseAddr));
30+
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_wait_bus_busy_ram(void));
31+
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_flash_erase_sector_ram(uint32_t address));
32+
AT_QUICKACCESS_SECTION_CODE(static void flexspi_lower_clock_ram(void));
33+
AT_QUICKACCESS_SECTION_CODE(static void flexspi_clock_update_ram(void));
34+
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_flash_page_program_ram(uint32_t address,
35+
const uint32_t *src,
36+
uint32_t size));
37+
AT_QUICKACCESS_SECTION_CODE(void flexspi_nor_flash_read_data_ram(uint32_t addr,
38+
uint32_t *buffer,
39+
uint32_t size));
40+
41+
void flexspi_update_lut_ram(void)
42+
{
43+
flexspi_config_t config;
44+
45+
/*Get FLEXSPI default settings and configure the flexspi. */
46+
FLEXSPI_GetDefaultConfig(&config);
47+
48+
/*Set AHB buffer size for reading data through AHB bus. */
49+
config.ahbConfig.enableAHBPrefetch = true;
50+
/*Allow AHB read start address do not follow the alignment requirement. */
51+
config.ahbConfig.enableReadAddressOpt = true;
52+
config.ahbConfig.enableAHBBufferable = true;
53+
config.ahbConfig.enableAHBCachable = true;
54+
/* enable diff clock and DQS */
55+
config.enableSckBDiffOpt = true;
56+
config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad;
57+
config.enableCombination = true;
58+
FLEXSPI_Init(FLEXSPI, &config);
59+
60+
/* Configure flash settings according to serial flash feature. */
61+
FLEXSPI_SetFlashConfig(FLEXSPI, &deviceconfig, kFLEXSPI_PortA1);
62+
63+
/* Update LUT table. */
64+
FLEXSPI_UpdateLUT(FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH);
65+
66+
FLEXSPI_SoftwareReset(FLEXSPI);
67+
68+
/* Wait for bus idle. */
69+
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
70+
}
71+
}
72+
73+
status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
74+
{
75+
flexspi_transfer_t flashXfer;
76+
status_t status;
77+
78+
/* Write enable */
79+
flashXfer.deviceAddress = baseAddr;
80+
flashXfer.port = kFLEXSPI_PortA1;
81+
flashXfer.cmdType = kFLEXSPI_Command;
82+
flashXfer.SeqNumber = 2;
83+
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE;
84+
85+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
86+
87+
return status;
88+
}
89+
90+
status_t flexspi_nor_wait_bus_busy_ram(void)
91+
{
92+
/* Wait status ready. */
93+
bool isBusy;
94+
uint32_t readValue;
95+
status_t status;
96+
flexspi_transfer_t flashXfer;
97+
98+
flashXfer.deviceAddress = 0;
99+
flashXfer.port = kFLEXSPI_PortA1;
100+
flashXfer.cmdType = kFLEXSPI_Read;
101+
flashXfer.SeqNumber = 2;
102+
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS;
103+
flashXfer.data = &readValue;
104+
flashXfer.dataSize = 2;
105+
106+
do {
107+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
108+
109+
if (status != kStatus_Success) {
110+
return status;
111+
}
112+
113+
if (readValue & 0x8000) {
114+
isBusy = false;
115+
} else {
116+
isBusy = true;
117+
}
118+
119+
if (readValue & 0x3200) {
120+
status = kStatus_Fail;
121+
break;
122+
}
123+
124+
} while (isBusy);
125+
126+
return status;
127+
128+
}
129+
130+
status_t flexspi_nor_flash_erase_sector_ram(uint32_t address)
131+
{
132+
status_t status;
133+
flexspi_transfer_t flashXfer;
134+
135+
/* Write enable */
136+
status = flexspi_nor_write_enable_ram(address);
137+
if (status != kStatus_Success) {
138+
return status;
139+
}
140+
141+
flashXfer.deviceAddress = address;
142+
flashXfer.port = kFLEXSPI_PortA1;
143+
flashXfer.cmdType = kFLEXSPI_Command;
144+
flashXfer.SeqNumber = 4;
145+
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR;
146+
147+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
148+
if (status != kStatus_Success) {
149+
return status;
150+
}
151+
152+
status = flexspi_nor_wait_bus_busy_ram();
153+
154+
/* Do software reset. */
155+
FLEXSPI_SoftwareReset(FLEXSPI);
156+
157+
return status;
158+
}
159+
160+
static void flexspi_lower_clock_ram(void)
161+
{
162+
unsigned int reg;
163+
164+
FLEXSPI_Enable(FLEXSPI, false);
165+
166+
/* Disable FlexSPI clock */
167+
CCM->CCGR6 &= ~CCM_CCGR6_CG5_MASK;
168+
169+
/* flexspi clock 66M, DDR mode, internal clock 33M. */
170+
reg = CCM->CSCMR1;
171+
reg &= ~CCM_CSCMR1_FLEXSPI_PODF_MASK;
172+
reg |= CCM_CSCMR1_FLEXSPI_PODF(3);
173+
CCM->CSCMR1 = reg;
174+
175+
/* Enable FlexSPI clock */
176+
CCM->CCGR6 |= CCM_CCGR6_CG5_MASK;
177+
178+
FLEXSPI_Enable(FLEXSPI, true);
179+
/* Do software reset. */
180+
FLEXSPI_SoftwareReset(FLEXSPI);
181+
/* Wait for bus idle. */
182+
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
183+
}
184+
}
185+
186+
static void flexspi_clock_update_ram(void)
187+
{
188+
/* Program finished, speed the clock to 133M. */
189+
/* Wait for bus idle before change flash configuration. */
190+
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
191+
}
192+
FLEXSPI_Enable(FLEXSPI, false);
193+
/* Disable FlexSPI clock */
194+
CCM->CCGR6 &= ~CCM_CCGR6_CG5_MASK;
195+
196+
/* flexspi clock 260M, DDR mode, internal clock 130M. */
197+
CCM->CSCMR1 &= ~CCM_CSCMR1_FLEXSPI_PODF_MASK;
198+
199+
/* Enable FlexSPI clock */
200+
CCM->CCGR6 |= CCM_CCGR6_CG5_MASK;
201+
202+
FLEXSPI_Enable(FLEXSPI, true);
203+
}
204+
205+
status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *src, uint32_t size)
206+
{
207+
status_t status;
208+
flexspi_transfer_t flashXfer;
209+
210+
flexspi_lower_clock_ram();
211+
212+
/* Write enable */
213+
status = flexspi_nor_write_enable_ram(address);
214+
215+
if (status != kStatus_Success) {
216+
return status;
217+
}
218+
219+
/* Prepare page program command */
220+
flashXfer.deviceAddress = address;
221+
flashXfer.port = kFLEXSPI_PortA1;
222+
flashXfer.cmdType = kFLEXSPI_Write;
223+
flashXfer.SeqNumber = 2;
224+
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM;
225+
flashXfer.data = (uint32_t *)src;
226+
flashXfer.dataSize = size;
227+
228+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
229+
230+
if (status != kStatus_Success) {
231+
return status;
232+
}
233+
234+
status = flexspi_nor_wait_bus_busy_ram();
235+
236+
flexspi_clock_update_ram();
237+
238+
/* Do software reset. */
239+
FLEXSPI_SoftwareReset(FLEXSPI);
240+
241+
return status;
242+
}
243+
244+
void flexspi_nor_flash_read_data_ram(uint32_t addr, uint32_t *buffer, uint32_t size)
245+
{
246+
memcpy(buffer, (void *)addr, size);
247+
}
248+
249+
int32_t flash_init(flash_t *obj)
250+
{
251+
flexspi_update_lut_ram();
252+
253+
return 0;
254+
}
255+
256+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
257+
{
258+
status_t status;
259+
int32_t ret = 0;
260+
261+
core_util_critical_section_enter();
262+
263+
status = flexspi_nor_flash_erase_sector_ram(address - FlexSPI_AMBA_BASE);
264+
265+
if (status != kStatus_Success) {
266+
ret = -1;
267+
} else {
268+
DCACHE_InvalidateByRange(address, BOARD_FLASH_SECTOR_SIZE);
269+
}
270+
271+
core_util_critical_section_exit();
272+
273+
return ret;
274+
}
275+
276+
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
277+
{
278+
status_t status;
279+
int32_t ret = 0;
280+
281+
core_util_critical_section_enter();
282+
283+
status = flexspi_nor_flash_page_program_ram(address - FlexSPI_AMBA_BASE, (uint32_t *)data, size);
284+
285+
if (status != kStatus_Success) {
286+
ret = -1;
287+
} else {
288+
DCACHE_InvalidateByRange(address, size);
289+
}
290+
291+
core_util_critical_section_exit();
292+
293+
return ret;
294+
}
295+
296+
int32_t flash_read(flash_t *obj, uint32_t address, uint8_t *data, uint32_t size)
297+
{
298+
flexspi_nor_flash_read_data_ram(address, (uint32_t *)data, size);
299+
300+
return 0;
301+
}
302+
303+
int32_t flash_free(flash_t *obj)
304+
{
305+
return 0;
306+
}
307+
308+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
309+
{
310+
uint32_t sectorsize = MBED_FLASH_INVALID_SIZE;
311+
uint32_t devicesize = BOARD_FLASH_SIZE;
312+
uint32_t startaddr = BOARD_FLASH_START_ADDR;
313+
314+
if ((address >= startaddr) && (address < (startaddr + devicesize))) {
315+
sectorsize = BOARD_FLASH_SECTOR_SIZE;
316+
}
317+
318+
return sectorsize;
319+
}
320+
321+
uint32_t flash_get_page_size(const flash_t *obj)
322+
{
323+
return BOARD_FLASH_PAGE_SIZE;
324+
}
325+
326+
uint32_t flash_get_start_address(const flash_t *obj)
327+
{
328+
return BOARD_FLASH_START_ADDR;
329+
}
330+
331+
uint32_t flash_get_size(const flash_t *obj)
332+
{
333+
return BOARD_FLASH_SIZE;
334+
}
335+
336+
uint8_t flash_get_erase_value(const flash_t *obj)
337+
{
338+
(void)obj;
339+
340+
return 0xFF;
341+
}
342+
343+
#endif //DEVICE_FLASH
344+

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ struct trng_s {
6666
uint8_t dummy;
6767
};
6868

69+
#if DEVICE_FLASH
70+
struct flash_s {
71+
uint8_t dummy;
72+
};
73+
#endif
74+
6975
#include "gpio_object.h"
7076

7177
#ifdef __cplusplus

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/device.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@
1919
#define MBED_DEVICE_H
2020

2121
#define DEVICE_ID_LENGTH 24
22-
#define BOARD_FLASH_SIZE (0x4000000U)
22+
/* 4MB reserved for mbed-os */
23+
#define BOARD_FLASH_SIZE (0x3C00000U)
24+
#define BOARD_FLASH_START_ADDR (0x60400000U)
25+
26+
#define BOARD_FLASH_PAGE_SIZE (512)
27+
#define BOARD_FLASH_SECTOR_SIZE (262144)
28+
2329
#define BOARD_ENET_PHY_ADDR (2)
2430

2531
#include "objects.h"

0 commit comments

Comments
 (0)