@@ -56,100 +56,138 @@ TODO
56
56
#define MBED_HAL_QSPI_HZ_TO_CONFIG (hz ) ((32000000/(hz))-1)
57
57
#define MBED_HAL_QSPI_MAX_FREQ 32000000UL
58
58
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
+
59
71
static nrf_drv_qspi_config_t config ;
60
72
61
73
// Private helper function to track initialization
62
74
static ret_code_t _qspi_drv_init (void );
63
75
64
76
qspi_status_t qspi_prepare_command (qspi_t * obj , const qspi_command_t * command , bool write )
65
77
{
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 ) {
69
85
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 ) {
82
87
config .prot_if .writeoc = NRF_QSPI_WRITEOC_PP ;
83
88
} else {
89
+ return QSPI_STATUS_INVALID_PARAMETER ;
90
+ }
91
+ } else {
92
+ if (command -> instruction .value == FAST_READ_opcode ) {
84
93
config .prot_if .readoc = NRF_QSPI_READOC_FASTREAD ;
94
+ } else {
95
+ return QSPI_STATUS_INVALID_PARAMETER ;
85
96
}
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 ) {
92
105
config .prot_if .writeoc = NRF_QSPI_WRITEOC_PP4O ;
93
106
} else {
107
+ return QSPI_STATUS_INVALID_PARAMETER ;
108
+ }
109
+ } else {
110
+ if (command -> instruction .value == READ4O_opcode ) {
94
111
config .prot_if .readoc = NRF_QSPI_READOC_READ4O ;
112
+ } else {
113
+ return QSPI_STATUS_INVALID_PARAMETER ;
95
114
}
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 ) {
102
123
config .prot_if .writeoc = NRF_QSPI_WRITEOC_PP4IO ;
103
124
} else {
125
+ return QSPI_STATUS_INVALID_PARAMETER ;
126
+ }
127
+ } else {
128
+ if (command -> instruction .value == READ4IO_opcode ) {
104
129
config .prot_if .readoc = NRF_QSPI_READOC_READ4IO ;
130
+ } else {
131
+ return QSPI_STATUS_INVALID_PARAMETER ;
105
132
}
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 ) {
106
138
// 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 ) {
112
141
config .prot_if .writeoc = NRF_QSPI_WRITEOC_PP2O ;
113
142
} else {
143
+ return QSPI_STATUS_INVALID_PARAMETER ;
144
+ }
145
+ } else {
146
+ if (command -> instruction .value == READ2O_opcode ) {
114
147
config .prot_if .readoc = NRF_QSPI_READOC_READ2O ;
148
+ } else {
149
+ return QSPI_STATUS_INVALID_PARAMETER ;
115
150
}
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 ) {
116
156
// 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 ) {
125
162
config .prot_if .readoc = NRF_QSPI_READOC_READ2IO ;
163
+ } else {
164
+ return QSPI_STATUS_INVALID_PARAMETER ;
126
165
}
127
166
}
128
- }
167
+ } else {
168
+ return QSPI_STATUS_INVALID_PARAMETER ;
169
+ }
129
170
130
- qspi_status_t ret = QSPI_STATUS_OK ;
131
171
// supporting only 24 or 32 bit address
132
172
if (command -> address .size == QSPI_CFG_ADDR_SIZE_24 ) {
133
173
config .prot_if .addrmode = NRF_QSPI_ADDRMODE_24BIT ;
134
174
} else if (command -> address .size == QSPI_CFG_ADDR_SIZE_32 ) {
135
175
config .prot_if .addrmode = NRF_QSPI_ADDRMODE_32BIT ;
136
176
} else {
137
- ret = QSPI_STATUS_INVALID_PARAMETER ;
177
+ return QSPI_STATUS_INVALID_PARAMETER ;
138
178
}
139
179
140
180
//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 ;
149
187
}
150
188
}
151
189
152
- return ret ;
190
+ return QSPI_STATUS_OK ;
153
191
}
154
192
155
193
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
169
207
config .pins .io3_pin = (uint32_t )io3 ;
170
208
config .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY ;
171
209
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 ;
174
212
config .phy_if .dpmen = false;
175
213
config .phy_if .spi_mode = mode == 0 ? NRF_QSPI_MODE_0 : NRF_QSPI_MODE_1 ;
176
214
0 commit comments