Skip to content

Commit 1ec8c79

Browse files
NRF5: fix qspi R/W opcodes mapping
1 parent f5cb477 commit 1ec8c79

File tree

1 file changed

+92
-54
lines changed

1 file changed

+92
-54
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/qspi_api.c

Lines changed: 92 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -56,100 +56,138 @@ TODO
5656
#define MBED_HAL_QSPI_HZ_TO_CONFIG(hz) ((32000000/(hz))-1)
5757
#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
5858

59+
// NRF supported R/W opcodes
60+
#define FAST_READ_opcode 0x0B
61+
#define READ2O_opcode 0x3B
62+
#define READ2IO_opcode 0xBB
63+
#define READ4O_opcode 0x6B
64+
#define READ4IO_opcode 0xEB
65+
66+
#define PP_opcode 0x02
67+
#define PP2O_opcode 0xA2
68+
#define PP4O_opcode 0x32
69+
#define PP4IO_opcode 0x38
70+
5971
static nrf_drv_qspi_config_t config;
6072

6173
// Private helper function to track initialization
6274
static ret_code_t _qspi_drv_init(void);
6375

6476
qspi_status_t qspi_prepare_command(qspi_t *obj, const qspi_command_t *command, bool write)
6577
{
66-
//Use custom command if provided by the caller
67-
if(command->instruction.value != 0) {
68-
//Use custom command if provided
78+
// we need to remap opcodes to NRF ID's
79+
// most commmon are 1-1-1, 1-1-4, 1-4-4
80+
81+
// 1-1-1
82+
if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
83+
command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
84+
command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
6985
if (write) {
70-
config.prot_if.writeoc = (nrf_qspi_writeoc_t)command->instruction.value;
71-
} else {
72-
config.prot_if.readoc = (nrf_qspi_readoc_t)command->instruction.value;
73-
}
74-
} else {
75-
// we need to remap to command-address-data - x_x_x
76-
// most commmon are 1-1-1, 1-1-4, 1-4-4
77-
// 1-1-1
78-
if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
79-
command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
80-
command->data.bus_width == QSPI_CFG_BUS_SINGLE) {
81-
if (write) {
86+
if (command->instruction.value == PP_opcode) {
8287
config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP;
8388
} else {
89+
return QSPI_STATUS_INVALID_PARAMETER;
90+
}
91+
} else {
92+
if (command->instruction.value == FAST_READ_opcode) {
8493
config.prot_if.readoc = NRF_QSPI_READOC_FASTREAD;
94+
} else {
95+
return QSPI_STATUS_INVALID_PARAMETER;
8596
}
86-
// 1-1-4
87-
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
88-
command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
89-
command->data.bus_width == QSPI_CFG_BUS_QUAD) {
90-
// 1_1_4
91-
if (write) {
97+
}
98+
// 1-1-4
99+
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
100+
command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
101+
command->data.bus_width == QSPI_CFG_BUS_QUAD) {
102+
// 1_1_4
103+
if (write) {
104+
if (command->instruction.value == PP4O_opcode) {
92105
config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4O;
93106
} else {
107+
return QSPI_STATUS_INVALID_PARAMETER;
108+
}
109+
} else {
110+
if (command->instruction.value == READ4O_opcode) {
94111
config.prot_if.readoc = NRF_QSPI_READOC_READ4O;
112+
} else {
113+
return QSPI_STATUS_INVALID_PARAMETER;
95114
}
96-
// 1-4-4
97-
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
98-
command->address.bus_width == QSPI_CFG_BUS_QUAD &&
99-
command->data.bus_width == QSPI_CFG_BUS_QUAD) {
100-
// 1_4_4
101-
if (write) {
115+
}
116+
// 1-4-4
117+
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
118+
command->address.bus_width == QSPI_CFG_BUS_QUAD &&
119+
command->data.bus_width == QSPI_CFG_BUS_QUAD) {
120+
// 1_4_4
121+
if (write) {
122+
if (command->instruction.value == PP4IO_opcode) {
102123
config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP4IO;
103124
} else {
125+
return QSPI_STATUS_INVALID_PARAMETER;
126+
}
127+
} else {
128+
if (command->instruction.value == READ4IO_opcode) {
104129
config.prot_if.readoc = NRF_QSPI_READOC_READ4IO;
130+
} else {
131+
return QSPI_STATUS_INVALID_PARAMETER;
105132
}
133+
}
134+
// 1-1-2
135+
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
136+
command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
137+
command->data.bus_width == QSPI_CFG_BUS_DUAL) {
106138
// 1-1-2
107-
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
108-
command->address.bus_width == QSPI_CFG_BUS_SINGLE &&
109-
command->data.bus_width == QSPI_CFG_BUS_DUAL) {
110-
// 1-1-2
111-
if (write) {
139+
if (write) {
140+
if (command->instruction.value == PP2O_opcode) {
112141
config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
113142
} else {
143+
return QSPI_STATUS_INVALID_PARAMETER;
144+
}
145+
} else {
146+
if (command->instruction.value == READ2O_opcode) {
114147
config.prot_if.readoc = NRF_QSPI_READOC_READ2O;
148+
} else {
149+
return QSPI_STATUS_INVALID_PARAMETER;
115150
}
151+
}
152+
// 1-2-2
153+
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
154+
command->address.bus_width == QSPI_CFG_BUS_DUAL &&
155+
command->data.bus_width == QSPI_CFG_BUS_DUAL) {
116156
// 1-2-2
117-
} else if (command->instruction.bus_width == QSPI_CFG_BUS_SINGLE &&
118-
command->address.bus_width == QSPI_CFG_BUS_DUAL &&
119-
command->data.bus_width == QSPI_CFG_BUS_DUAL) {
120-
// 1-2-2
121-
if (write) {
122-
//Currently NRF52840 does not define PP2IO, so use PP2O for 1-2-2 mode
123-
config.prot_if.writeoc = NRF_QSPI_WRITEOC_PP2O;
124-
} else {
157+
if (write) {
158+
// 1-2-2 write is not supported
159+
return QSPI_STATUS_INVALID_PARAMETER;
160+
} else {
161+
if (command->instruction.value == READ2IO_opcode) {
125162
config.prot_if.readoc = NRF_QSPI_READOC_READ2IO;
163+
} else {
164+
return QSPI_STATUS_INVALID_PARAMETER;
126165
}
127166
}
128-
}
167+
} else {
168+
return QSPI_STATUS_INVALID_PARAMETER;
169+
}
129170

130-
qspi_status_t ret = QSPI_STATUS_OK;
131171
// supporting only 24 or 32 bit address
132172
if (command->address.size == QSPI_CFG_ADDR_SIZE_24) {
133173
config.prot_if.addrmode = NRF_QSPI_ADDRMODE_24BIT;
134174
} else if (command->address.size == QSPI_CFG_ADDR_SIZE_32) {
135175
config.prot_if.addrmode = NRF_QSPI_ADDRMODE_32BIT;
136176
} else {
137-
ret = QSPI_STATUS_INVALID_PARAMETER;
177+
return QSPI_STATUS_INVALID_PARAMETER;
138178
}
139179

140180
//Configure QSPI with new command format
141-
if(ret == QSPI_STATUS_OK) {
142-
ret_code_t ret_status = _qspi_drv_init();
143-
if (ret_status != NRF_SUCCESS ) {
144-
if (ret_status == NRF_ERROR_INVALID_PARAM) {
145-
return QSPI_STATUS_INVALID_PARAMETER;
146-
} else {
147-
return QSPI_STATUS_ERROR;
148-
}
181+
ret_code_t ret_status = _qspi_drv_init();
182+
if (ret_status != NRF_SUCCESS ) {
183+
if (ret_status == NRF_ERROR_INVALID_PARAM) {
184+
return QSPI_STATUS_INVALID_PARAMETER;
185+
} else {
186+
return QSPI_STATUS_ERROR;
149187
}
150188
}
151189

152-
return ret;
190+
return QSPI_STATUS_OK;
153191
}
154192

155193
qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinName io3, PinName sclk, PinName ssel, uint32_t hz, uint8_t mode)
@@ -169,8 +207,8 @@ qspi_status_t qspi_init(qspi_t *obj, PinName io0, PinName io1, PinName io2, PinN
169207
config.pins.io3_pin = (uint32_t)io3;
170208
config.irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
171209

172-
config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz),
173-
config.phy_if.sck_delay = 0x05,
210+
config.phy_if.sck_freq = (nrf_qspi_frequency_t)MBED_HAL_QSPI_HZ_TO_CONFIG(hz);
211+
config.phy_if.sck_delay = 0x05;
174212
config.phy_if.dpmen = false;
175213
config.phy_if.spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1;
176214

0 commit comments

Comments
 (0)