Skip to content

Commit 9135418

Browse files
author
Cruz Monrreal
authored
Merge pull request #7825 from SiliconLabs/siliconlabs-qspi
Silicon Labs QSPI HAL implementation
2 parents 1b051c7 + 55c6dad commit 9135418

File tree

10 files changed

+678
-2
lines changed

10 files changed

+678
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018-2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#ifndef MBED_QSPI_FLASH_MX25R3235F_H
17+
#define MBED_QSPI_FLASH_MX25R3235F_H
18+
19+
20+
#define QSPI_FLASH_CHIP_STRING "macronix MX25R3235F"
21+
22+
// Command for reading status register
23+
#define QSPI_CMD_RDSR 0x05
24+
// Command for reading configuration register
25+
#define QSPI_CMD_RDCR0 0x15
26+
// Command for writing status/configuration register
27+
#define QSPI_CMD_WRSR 0x01
28+
// Command for reading security register
29+
#define QSPI_CMD_RDSCUR 0x2B
30+
31+
// Command for setting Reset Enable
32+
#define QSPI_CMD_RSTEN 0x66
33+
// Command for setting Reset
34+
#define QSPI_CMD_RST 0x99
35+
36+
// Command for setting write enable
37+
#define QSPI_CMD_WREN 0x06
38+
// Command for setting write disable
39+
#define QSPI_CMD_WRDI 0x04
40+
41+
// WRSR operations max time [us] (datasheet max time + 15%)
42+
#define QSPI_WRSR_MAX_TIME 34500 // 30ms
43+
// general wait max time [us]
44+
#define QSPI_WAIT_MAX_TIME 100000 // 100ms
45+
46+
47+
// Commands for writing (page programming)
48+
#define QSPI_CMD_WRITE_1IO 0x02 // 1-1-1 mode
49+
#define QSPI_CMD_WRITE_4IO 0x38 // 1-4-4 mode
50+
51+
// write operations max time [us] (datasheet max time + 15%)
52+
#define QSPI_PAGE_PROG_MAX_TIME 11500 // 10ms
53+
54+
#define QSPI_PAGE_SIZE 256 // 256B
55+
56+
// Commands for reading
57+
#define QSPI_CMD_READ_1IO_FAST 0x0B // 1-1-1 mode
58+
#define QSPI_CMD_READ_1IO 0x03 // 1-1-1 mode
59+
#define QSPI_CMD_READ_2IO 0xBB // 1-2-2 mode
60+
#define QSPI_CMD_READ_1I2O 0x3B // 1-1-2 mode
61+
#define QSPI_CMD_READ_4IO 0xEB // 1-4-4 mode
62+
#define QSPI_CMD_READ_1I4O 0x6B // 1-1-4 mode
63+
64+
#define QSPI_READ_1IO_DUMMY_CYCLE 0
65+
#define QSPI_READ_FAST_DUMMY_CYCLE 8
66+
#define QSPI_READ_2IO_DUMMY_CYCLE 4
67+
#define QSPI_READ_1I2O_DUMMY_CYCLE 8
68+
#define QSPI_READ_4IO_DUMMY_CYCLE 6
69+
#define QSPI_READ_1I4O_DUMMY_CYCLE 8
70+
71+
// Commands for erasing
72+
#define QSPI_CMD_ERASE_SECTOR 0x20 // 4kB
73+
#define QSPI_CMD_ERASE_BLOCK_32 0x52 // 32kB
74+
#define QSPI_CMD_ERASE_BLOCK_64 0xD8 // 64kB
75+
#define QSPI_CMD_ERASE_CHIP 0x60 // or 0xC7
76+
77+
// erase operations max time [us] (datasheet max time + 15%)
78+
#define QSPI_ERASE_SECTOR_MAX_TIME 276000 // 240 ms
79+
#define QSPI_ERASE_BLOCK_32_MAX_TIME 3450000 // 3s
80+
#define QSPI_ERASE_BLOCK_64_MAX_TIME 4025000 // 3.5s
81+
82+
// max frequency for basic rw operation
83+
#define QSPI_COMMON_MAX_FREQUENCY 32000000
84+
85+
#define QSPI_STATUS_REG_SIZE 1
86+
#define QSPI_CONFIG_REG_0_SIZE 2
87+
#define QSPI_SECURITY_REG_SIZE 1
88+
#define QSPI_MAX_REG_SIZE 2
89+
90+
// status register
91+
#define STATUS_BIT_WIP (1 << 0) // write in progress bit
92+
#define STATUS_BIT_WEL (1 << 1) // write enable latch
93+
#define STATUS_BIT_BP0 (1 << 2) //
94+
#define STATUS_BIT_BP1 (1 << 3) //
95+
#define STATUS_BIT_BP2 (1 << 4) //
96+
#define STATUS_BIT_BP3 (1 << 5) //
97+
#define STATUS_BIT_QE (1 << 6) // Quad Enable
98+
#define STATUS_BIT_SRWD (1 << 7) // status register write protect
99+
100+
// configuration register 0
101+
// bit 0, 1, 2, 4, 5, 7 reserved
102+
#define CONFIG0_BIT_TB (1 << 3) // Top/Bottom area protect
103+
#define CONFIG0_BIT_DC (1 << 6) // Dummy Cycle
104+
105+
// configuration register 1
106+
// bit 0, 2, 3, 4, 5, 6, 7 reserved
107+
#define CONFIG1_BIT_LH (1 << 1) // 0 = Ultra Low power mode, 1 = High performance mode
108+
109+
110+
// single quad enable flag for both dual and quad mode
111+
#define QUAD_ENABLE() \
112+
\
113+
uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \
114+
\
115+
if (write_enable(qspi) != QSPI_STATUS_OK) { \
116+
return QSPI_STATUS_ERROR; \
117+
} \
118+
WAIT_FOR(WRSR_MAX_TIME, qspi); \
119+
\
120+
reg_data[0] = STATUS_BIT_QE; \
121+
qspi.cmd.build(QSPI_CMD_WRSR); \
122+
\
123+
if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \
124+
reg_data, QSPI_STATUS_REG_SIZE, NULL, 0) != QSPI_STATUS_OK) { \
125+
return QSPI_STATUS_ERROR; \
126+
} \
127+
WAIT_FOR(WRSR_MAX_TIME, qspi); \
128+
\
129+
memset(reg_data, 0, QSPI_STATUS_REG_SIZE); \
130+
if (read_register(STATUS_REG, reg_data, \
131+
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
132+
return QSPI_STATUS_ERROR; \
133+
} \
134+
\
135+
return ((reg_data[0] & STATUS_BIT_QE) != 0 ? \
136+
QSPI_STATUS_OK : QSPI_STATUS_ERROR)
137+
138+
139+
140+
#define QUAD_DISABLE() \
141+
\
142+
uint8_t reg_data[QSPI_STATUS_REG_SIZE]; \
143+
\
144+
if (write_enable(qspi) != QSPI_STATUS_OK) { \
145+
return QSPI_STATUS_ERROR; \
146+
} \
147+
WAIT_FOR(WRSR_MAX_TIME, qspi); \
148+
\
149+
reg_data[0] = 0; \
150+
qspi.cmd.build(QSPI_CMD_WRSR); \
151+
\
152+
if (qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \
153+
reg_data, QSPI_STATUS_REG_SIZE, NULL, 0) != QSPI_STATUS_OK) { \
154+
return QSPI_STATUS_ERROR; \
155+
} \
156+
WAIT_FOR(WRSR_MAX_TIME, qspi); \
157+
\
158+
reg_data[0] = 0; \
159+
if (read_register(STATUS_REG, reg_data, \
160+
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
161+
return QSPI_STATUS_ERROR; \
162+
} \
163+
\
164+
return ((reg_data[0] & STATUS_BIT_QE) == 0 ? \
165+
QSPI_STATUS_OK : QSPI_STATUS_ERROR)
166+
167+
168+
169+
#define FAST_MODE_ENABLE() \
170+
\
171+
qspi_status_t ret; \
172+
const int32_t reg_size = QSPI_STATUS_REG_SIZE + QSPI_CONFIG_REG_0_SIZE; \
173+
uint8_t reg_data[reg_size]; \
174+
\
175+
if (read_register(STATUS_REG, reg_data, \
176+
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
177+
return QSPI_STATUS_ERROR; \
178+
} \
179+
if (read_register(CONFIG_REG0, reg_data + QSPI_STATUS_REG_SIZE, \
180+
QSPI_CONFIG_REG_0_SIZE, qspi) != QSPI_STATUS_OK) { \
181+
return QSPI_STATUS_ERROR; \
182+
} \
183+
\
184+
reg_data[2] |= CONFIG1_BIT_LH; \
185+
qspi.cmd.build(QSPI_CMD_WRSR); \
186+
\
187+
return qspi_command_transfer(&qspi.handle, qspi.cmd.get(), \
188+
reg_data, reg_size, NULL, 0)
189+
190+
191+
192+
#endif // MBED_QSPI_FLASH_MX25R3235F_H
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018-2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#ifndef MBED_QSPI_FLASH_CONFIG_H
17+
#define MBED_QSPI_FLASH_CONFIG_H
18+
19+
#include "../../MX25R3235F_config.h"
20+
21+
22+
#endif // MBED_QSPI_FLASH_CONFIG_H

TESTS/mbed_hal/qspi/flash_configs/flash_configs.h

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "NORDIC/NRF52840_DK/flash_config.h"
2424
#elif defined(TARGET_DISCO_F413ZH)
2525
#include "STM/DISCO_F413ZH/flash_config.h"
26+
#elif defined(TARGET_EFM32GG11_STK3701)
27+
#include "SiliconLabs/EFM32GG11_STK3701/flash_config.h"
2628
#endif
2729

2830
#endif // MBED_FLASH_CONFIGS_H

targets/TARGET_Silicon_Labs/TARGET_EFM32/PeripheralNames.h

+8
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ typedef enum {
136136
} UARTName;
137137
#endif
138138

139+
#if DEVICE_QSPI
140+
typedef enum {
141+
#ifdef QSPI0_BASE
142+
QSPI_0 = QSPI0_BASE,
143+
#endif
144+
} QSPIName;
145+
#endif
146+
139147
#ifdef __cplusplus
140148
}
141149
#endif

targets/TARGET_Silicon_Labs/TARGET_EFM32/PeripheralPins.h

+10
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,15 @@ extern const PinMap PinMap_CAN_TX[];
6868
extern const PinMap PinMap_CAN_RX[];
6969
#endif
7070

71+
#if DEVICE_QSPI
72+
/************QSPI**************/
73+
extern const PinMap PinMap_QSPI_DQ0[];
74+
extern const PinMap PinMap_QSPI_DQ1[];
75+
extern const PinMap PinMap_QSPI_DQ2[];
76+
extern const PinMap PinMap_QSPI_DQ3[];
77+
extern const PinMap PinMap_QSPI_SCLK[];
78+
extern const PinMap PinMap_QSPI_CS0[];
79+
#endif
80+
7181
#endif
7282

targets/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG11/PeripheralPins.c

+50
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,53 @@ MBED_WEAK const PinMap PinMap_CAN_RX[] = {
579579
#endif
580580
};
581581
#endif
582+
583+
#if DEVICE_QSPI
584+
MBED_WEAK const PinMap PinMap_QSPI_DQ0[] = {
585+
#ifdef QSPI0_BASE
586+
{PD9, QSPI_0, 0},
587+
{PA2, QSPI_0, 1},
588+
{PG1, QSPI_0, 2},
589+
#endif
590+
};
591+
592+
MBED_WEAK const PinMap PinMap_QSPI_DQ1[] = {
593+
#ifdef QSPI0_BASE
594+
{PD10, QSPI_0, 0},
595+
{PA3, QSPI_0, 1},
596+
{PG2, QSPI_0, 2},
597+
#endif
598+
};
599+
600+
MBED_WEAK const PinMap PinMap_QSPI_DQ2[] = {
601+
#ifdef QSPI0_BASE
602+
{PD11, QSPI_0, 0},
603+
{PA4, QSPI_0, 1},
604+
{PG3, QSPI_0, 2},
605+
#endif
606+
};
607+
608+
MBED_WEAK const PinMap PinMap_QSPI_DQ3[] = {
609+
#ifdef QSPI0_BASE
610+
{PD12, QSPI_0, 0},
611+
{PA5, QSPI_0, 1},
612+
{PG4, QSPI_0, 2},
613+
#endif
614+
};
615+
616+
MBED_WEAK const PinMap PinMap_QSPI_SCLK[] = {
617+
#ifdef QSPI0_BASE
618+
{PF6, QSPI_0, 0},
619+
{PE14, QSPI_0, 1},
620+
{PG0, QSPI_0, 2},
621+
#endif
622+
};
623+
624+
MBED_WEAK const PinMap PinMap_QSPI_CS0[] = {
625+
#ifdef QSPI0_BASE
626+
{PF7, QSPI_0, 0},
627+
{PA0, QSPI_0, 1},
628+
{PG9, QSPI_0, 2},
629+
#endif
630+
};
631+
#endif

targets/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG11/TARGET_EFM32GG11_STK3701/PinNames.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,16 @@ typedef enum {
7676

7777
/* Board Controller */
7878
STDIO_UART_TX = USBTX,
79-
STDIO_UART_RX = USBRX
79+
STDIO_UART_RX = USBRX,
80+
81+
/* On-board MX25R3235F */
82+
QSPI_FLASH1_IO0 = PG1,
83+
QSPI_FLASH1_IO1 = PG2,
84+
QSPI_FLASH1_IO2 = PG3,
85+
QSPI_FLASH1_IO3 = PG4,
86+
QSPI_FLASH1_SCK = PG0,
87+
QSPI_FLASH1_CSN = PG9,
88+
8089
} PinName;
8190

8291
#ifdef __cplusplus

targets/TARGET_Silicon_Labs/TARGET_EFM32/common/objects.h

+12
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,18 @@ struct can_s {
154154
};
155155
#endif
156156

157+
#if DEVICE_QSPI
158+
struct qspi_s {
159+
QSPI_TypeDef *instance;
160+
PinName io0;
161+
PinName io1;
162+
PinName io2;
163+
PinName io3;
164+
PinName sclk;
165+
PinName ssel;
166+
};
167+
#endif
168+
157169
#ifdef __cplusplus
158170
}
159171
#endif

0 commit comments

Comments
 (0)