@@ -263,17 +263,19 @@ qspi_status_t qspi_frequency(qspi_t *obj, int hz)
263
263
264
264
qspi_status_t qspi_write (qspi_t * obj , const qspi_command_t * command , const void * data , size_t * length )
265
265
{
266
- // length needs to be rounded up to the next WORD (4 bytes)
267
- if ((* length & WORD_MASK ) > 0 ) {
266
+ // flash address and buffer length must be divisible by 4
267
+ if ((* length & WORD_MASK ) > 0 ||
268
+ (command -> address .value & WORD_MASK ) > 0 ) {
268
269
return QSPI_STATUS_INVALID_PARAMETER ;
269
270
}
270
-
271
+
271
272
qspi_status_t status = qspi_prepare_command (obj , command , true);
272
273
if (status != QSPI_STATUS_OK ) {
273
274
return status ;
274
275
}
275
276
276
- if (is_word_aligned (data )) {
277
+ if (is_word_aligned (data ) &&
278
+ nrf_drv_is_in_RAM (data )) {
277
279
// write here does not return how much it transfered, we return transfered all
278
280
ret_code_t ret = nrf_drv_qspi_write (data , * length , command -> address .value );
279
281
if (ret == NRF_SUCCESS ) {
@@ -283,7 +285,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
283
285
}
284
286
}
285
287
else {
286
- // if the data buffer is not WORD/4-byte aligned, use an aligned buffer on the stack
288
+ // if the data buffer is not WORD/4-byte aligned or in RAM , use an aligned buffer on the stack
287
289
uint32_t aligned_buffer [WORD_COUNT ];
288
290
uint32_t pos = 0 ;
289
291
size_t bytes_to_write = * length ;
@@ -298,6 +300,7 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
298
300
if (ret != NRF_SUCCESS ) {
299
301
return QSPI_STATUS_ERROR ;
300
302
}
303
+
301
304
pos += diff ;
302
305
bytes_to_write -= diff ;
303
306
}
@@ -307,28 +310,56 @@ qspi_status_t qspi_write(qspi_t *obj, const qspi_command_t *command, const void
307
310
308
311
qspi_status_t qspi_read (qspi_t * obj , const qspi_command_t * command , void * data , size_t * length )
309
312
{
310
- // length needs to be rounded up to the next WORD (4 bytes)
311
- if ((* length & WORD_MASK ) > 0 ) {
313
+ // flash address and buffer length must be divisible by 4
314
+ if ((* length & WORD_MASK ) > 0 ||
315
+ (command -> address .value & WORD_MASK ) > 0 ) {
312
316
return QSPI_STATUS_INVALID_PARAMETER ;
313
317
}
314
318
315
319
// check to see if this is an SFDP read
316
320
if (command -> instruction .value == READSFDP_opcode ) {
317
321
qspi_status_t status = sfdp_read (obj , command , data , length );
318
322
return status ;
319
- } else {
320
- qspi_status_t status = qspi_prepare_command (obj , command , false);
321
- if (status != QSPI_STATUS_OK ) {
322
- return status ;
323
+ }
324
+
325
+ qspi_status_t status = qspi_prepare_command (obj , command , false);
326
+ if (status != QSPI_STATUS_OK ) {
327
+ return status ;
328
+ }
329
+
330
+ if (is_word_aligned (data ) &&
331
+ nrf_drv_is_in_RAM (data )) {
332
+ ret_code_t ret = nrf_drv_qspi_read (data , * length , command -> address .value );
333
+ if (ret == NRF_SUCCESS ) {
334
+ return QSPI_STATUS_OK ;
335
+ } else {
336
+ return QSPI_STATUS_ERROR ;
323
337
}
324
338
}
339
+ else {
340
+ // if the data buffer is not WORD/4-byte aligned or in RAM, use an aligned buffer on the stack
341
+ uint32_t aligned_buffer [WORD_COUNT ];
342
+ uint32_t pos = 0 ;
343
+ size_t bytes_to_read = * length ;
325
344
326
- ret_code_t ret = nrf_drv_qspi_read (data , * length , command -> address .value );
327
- if (ret == NRF_SUCCESS ) {
328
- return QSPI_STATUS_OK ;
329
- } else {
330
- return QSPI_STATUS_ERROR ;
345
+ while (pos < * length ) {
346
+
347
+ size_t diff = bytes_to_read <= sizeof (aligned_buffer ) ? bytes_to_read : sizeof (aligned_buffer );
348
+
349
+ // read one buffer over QSPI
350
+ ret_code_t ret = nrf_drv_qspi_read (aligned_buffer , diff , command -> address .value + pos );
351
+ if (ret != NRF_SUCCESS ) {
352
+ return QSPI_STATUS_ERROR ;
353
+ }
354
+
355
+ // copy into original read buffer
356
+ memcpy (& ((uint8_t * )data )[pos ], aligned_buffer , diff );
357
+
358
+ pos += diff ;
359
+ bytes_to_read -= diff ;
360
+ }
331
361
}
362
+ return QSPI_STATUS_OK ;
332
363
}
333
364
334
365
qspi_status_t qspi_command_transfer (qspi_t * obj , const qspi_command_t * command , const void * tx_data , size_t tx_size , void * rx_data , size_t rx_size )
0 commit comments