Skip to content

Commit 211fca8

Browse files
committed
applications: sdp: mspi: add QUAD mode to RX
Add support for QAD mode in RX path. Signed-off-by: Magdalena Pastula <magdalena.pastula@nordicsemi.no>
1 parent ef49118 commit 211fca8

File tree

3 files changed

+177
-54
lines changed

3 files changed

+177
-54
lines changed

applications/sdp/mspi/src/hrt/hrt-nrf54l15.s

+107-39
Original file line numberDiff line numberDiff line change
@@ -165,15 +165,21 @@ hrt_tx:
165165
.align 1
166166
.type hrt_tx_rx.constprop.0, @function
167167
hrt_tx_rx.constprop.0:
168-
lw a5,0(a0)
169-
lw a4,4(a0)
170-
beq a4,zero,.L18
171-
lw a4,0(a5)
172-
slli a1,a1,12
173-
li a5,126976
174-
and a1,a1,a5
168+
lw a4,0(a0)
169+
mv a5,a1
170+
lw a1,4(a0)
171+
beq a1,zero,.L18
172+
li a1,8
173+
div a1,a1,a5
174+
li t1,126976
175+
slli a5,a5,12
176+
and a5,a5,t1
177+
lw a4,0(a4)
178+
addi a1,a1,-1
179+
andi a1,a1,63
180+
or a1,a1,a5
175181
li a5,2097152
176-
addi a5,a5,1031
182+
addi a5,a5,1024
177183
or a1,a1,a5
178184
#APP
179185
csrw 3019, a1
@@ -418,9 +424,12 @@ hrt_read:
418424
addi sp,sp,-12
419425
sw s0,4(sp)
420426
sw ra,8(sp)
427+
sw s1,0(sp)
428+
lbu s1,83(a0)
421429
lbu a5,89(a0)
422430
lbu a4,87(a0)
423431
mv s0,a0
432+
andi s1,s1,0xff
424433
bne a5,zero,.L55
425434
li a5,1
426435
sll a5,a5,a4
@@ -430,6 +439,9 @@ hrt_read:
430439
csrc 3008, a5
431440
#NO_APP
432441
.L56:
442+
lbu a4,83(s0)
443+
li a5,1
444+
bne a4,a5,.L57
433445
lhu a5,90(s0)
434446
slli a5,a5,16
435447
srli a5,a5,16
@@ -440,6 +452,9 @@ hrt_read:
440452
lhu a5,90(s0)
441453
#APP
442454
csrw 3009, a5
455+
#NO_APP
456+
.L57:
457+
#APP
443458
csrw 3011, 2
444459
#NO_APP
445460
li a5,65536
@@ -487,37 +502,87 @@ hrt_read:
487502
li a2,0
488503
addi a0,s0,20
489504
call hrt_tx_rx.constprop.0
490-
li a5,0
491-
.L57:
492-
lw a4,64(s0)
493-
bltu a5,a4,.L58
505+
lbu a4,83(s0)
506+
li a5,1
507+
beq a4,a5,.L58
508+
lhu a5,92(s0)
509+
#APP
510+
csrw 3009, a5
511+
#NO_APP
512+
.L58:
513+
lbu a4,81(s0)
514+
lbu a5,83(s0)
515+
beq a4,a5,.L66
516+
li a5,2031616
517+
slli s1,s1,16
518+
and s1,s1,a5
519+
ori s1,s1,4
520+
#APP
521+
csrw 3043, s1
522+
#NO_APP
523+
lbu a4,83(s0)
524+
li a5,8
525+
div a5,a5,a4
526+
addi a5,a5,-1
527+
andi a5,a5,0xff
528+
#APP
529+
csrw 3023, a5
530+
csrr a5, 3018
531+
#NO_APP
532+
li a4,4
533+
.L60:
534+
lw a3,64(s0)
535+
bgtu a3,a4,.L61
494536
#APP
495537
csrw 2000, 0
496538
csrw 2001, 0
497539
csrw 3019, 0
498540
#NO_APP
499-
lbu a5,88(s0)
500-
bne a5,zero,.L59
501-
lbu a5,89(s0)
502-
lbu a4,87(s0)
503-
bne a5,zero,.L60
504-
li a5,1
505-
sll a5,a5,a4
506-
slli a5,a5,16
507-
srli a5,a5,16
541+
lbu a4,88(s0)
542+
bne a4,zero,.L62
543+
lbu a4,89(s0)
544+
lbu a3,87(s0)
545+
bne a4,zero,.L63
546+
li a4,1
547+
sll a4,a4,a3
548+
slli a4,a4,16
549+
srli a4,a4,16
508550
#APP
509-
csrs 3008, a5
551+
csrs 3008, a4
510552
#NO_APP
511-
.L59:
553+
.L62:
554+
lbu a3,81(s0)
555+
lbu a4,83(s0)
556+
beq a3,a4,.L64
557+
lw a4,60(s0)
558+
andi a3,a5,0xff
559+
sb a3,0(a4)
560+
lw a3,60(s0)
561+
srli a4,a5,8
562+
andi a4,a4,0xff
563+
sb a4,1(a3)
564+
lw a3,60(s0)
565+
srli a4,a5,16
566+
andi a4,a4,0xff
567+
sb a4,2(a3)
568+
lw a4,60(s0)
569+
srli a5,a5,24
570+
sb a5,3(a4)
571+
.L64:
572+
lbu a4,83(s0)
573+
li a5,1
574+
bne a4,a5,.L54
512575
lhu a5,90(s0)
513576
ori a5,a5,4
514577
sh a5,90(s0)
515578
lhu a5,90(s0)
516579
#APP
517580
csrw 3009, a5
518581
#NO_APP
582+
.L54:
519583
lw ra,8(sp)
520584
lw s0,4(sp)
585+
lw s1,0(sp)
521586
addi sp,sp,12
522587
jr ra
523588
.L55:
@@ -529,26 +594,29 @@ hrt_read:
529594
csrs 3008, a5
530595
#NO_APP
531596
j .L56
532-
.L58:
597+
.L61:
533598
#APP
534-
csrr a3, 3018
599+
csrr a2, 3018
535600
#NO_APP
536-
lw a4,60(s0)
537-
srli a3,a3,24
538-
add a4,a4,a5
539-
addi a5,a5,1
540-
sb a3,0(a4)
541-
andi a5,a5,0xff
542-
j .L57
543-
.L60:
544-
li a5,1
545-
sll a5,a5,a4
546-
slli a5,a5,16
547-
srli a5,a5,16
601+
lw a3,60(s0)
602+
srli a2,a2,24
603+
add a3,a3,a4
604+
sb a2,0(a3)
605+
addi a4,a4,1
606+
j .L60
607+
.L66:
608+
li a4,0
609+
li a5,0
610+
j .L60
611+
.L63:
612+
li a4,1
613+
sll a4,a4,a3
614+
slli a4,a4,16
615+
srli a4,a4,16
548616
#APP
549-
csrc 3008, a5
617+
csrc 3008, a4
550618
#NO_APP
551-
j .L59
619+
j .L62
552620
.size hrt_read, .-hrt_read
553621
.section .sdata.xfer_shift_ctrl,"aw"
554622
.align 2

applications/sdp/mspi/src/hrt/hrt.c

+62-12
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
#define SPI_INPUT_PIN_NUM 2
1414
#define CNT1_INIT_VALUE 1
15-
#define MSB_MASK (0xff000000)
15+
#define MSB_MASK (0xff000000)
1616

17-
#define INPUT_SHIFT_COUNT (BITS_IN_WORD - BITS_IN_BYTE)
17+
#define FOURTH_BYTE_SHIFT_CNT 24
18+
#define THIRD_BYTE_SHIFT_CNT 16
19+
#define SECOND_BYTE_SHIFT_CNT 8
1820

1921
/*
2022
* Macro for calculating TOP value of CNT1. It should be twice as TOP value of CNT0
@@ -224,7 +226,7 @@ static void hrt_tx_rx(volatile hrt_xfer_data_t *xfer_data, uint8_t frame_width,
224226
uint16_t cnt0_val, uint16_t cnt1_val)
225227
{
226228
nrf_vpr_csr_vio_shift_ctrl_t shift_ctrl = {
227-
.shift_count = BITS_IN_BYTE - 1,
229+
.shift_count = SHIFTCNTB_VALUE(BITS_IN_BYTE / frame_width),
228230
.out_mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE,
229231
.frame_width = frame_width,
230232
.in_mode = NRF_VPR_CSR_VIO_MODE_IN_SHIFT,
@@ -279,6 +281,13 @@ void hrt_read(volatile hrt_xfer_t *hrt_xfer_params)
279281
.mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE,
280282
.frame_width = 1,
281283
};
284+
nrf_vpr_csr_vio_mode_out_t out_mode_in = {
285+
.mode = NRF_VPR_CSR_VIO_SHIFT_OUTB_TOGGLE,
286+
.frame_width = hrt_xfer_params->bus_widths.data,
287+
};
288+
289+
uint32_t rec_data = 0;
290+
uint32_t iter = 0;
282291

283292
/* Enable CS */
284293
if (hrt_xfer_params->ce_polarity == MSPI_CE_ACTIVE_LOW) {
@@ -288,9 +297,12 @@ void hrt_read(volatile hrt_xfer_t *hrt_xfer_params)
288297
}
289298

290299
/* Configure clock and pins */
291-
/* Set DQ1 as input */
292-
WRITE_BIT(hrt_xfer_params->tx_direction_mask, SPI_INPUT_PIN_NUM, VPRCSR_NORDIC_DIR_INPUT);
293-
nrf_vpr_csr_vio_dir_set(hrt_xfer_params->tx_direction_mask);
300+
/* Set DQ1 as input in SPI case. */
301+
if (hrt_xfer_params->bus_widths.data == 1) {
302+
WRITE_BIT(hrt_xfer_params->tx_direction_mask, SPI_INPUT_PIN_NUM,
303+
VPRCSR_NORDIC_DIR_INPUT);
304+
nrf_vpr_csr_vio_dir_set(hrt_xfer_params->tx_direction_mask);
305+
}
294306

295307
/* Initial configuration */
296308
nrf_vpr_csr_vio_mode_in_set(NRF_VPR_CSR_VIO_MODE_IN_SHIFT);
@@ -314,9 +326,36 @@ void hrt_read(volatile hrt_xfer_t *hrt_xfer_params)
314326
hrt_tx_rx(&hrt_xfer_params->xfer_data[HRT_FE_ADDRESS], hrt_xfer_params->bus_widths.address,
315327
false, hrt_xfer_params->counter_value, CNT1_INIT_VALUE);
316328

317-
for (uint8_t i = 0; i < hrt_xfer_params->xfer_data[HRT_FE_DATA].word_count; i++) {
318-
hrt_xfer_params->xfer_data[HRT_FE_DATA].data[i] =
319-
nrf_vpr_csr_vio_in_buffered_reversed_byte_get() >> INPUT_SHIFT_COUNT;
329+
/* Set pins as input for cases other than SINGLE mode. */
330+
if (hrt_xfer_params->bus_widths.data != 1) {
331+
nrf_vpr_csr_vio_dir_set(hrt_xfer_params->rx_direction_mask);
332+
}
333+
334+
if (hrt_xfer_params->bus_widths.address != hrt_xfer_params->bus_widths.data) {
335+
/*
336+
* When writing to SHIFTCTRLB, reception of data starts 6 clock cycles (3 bytes) too
337+
* late. When writing to OUTMODEB and SHIFTCNTB separately, the problem disappears.
338+
*/
339+
nrf_vpr_csr_vio_mode_out_buffered_set(&out_mode_in);
340+
nrf_vpr_csr_vio_shift_cnt_out_buffered_set(
341+
SHIFTCNTB_VALUE(BITS_IN_BYTE / hrt_xfer_params->bus_widths.data));
342+
343+
/*
344+
* When calling `vpr_csr_vio_in_buffered_reversed_byte_get` for the first time in
345+
* 1_1_4 mode, CPU stalls for 8 clock cycles instead of 2 (so there are 4 bytes in
346+
* the register, not 1). It is probably due to HW issue causing SHIFT_CNT_IN to be
347+
* updated one word too late. For this reason, read all four bytes at once, save
348+
* them in a temporary variable, and put them in buffer later to not perform not
349+
* needed operations during receive.
350+
*/
351+
rec_data = nrf_vpr_csr_vio_in_buffered_reversed_byte_get();
352+
iter = 4;
353+
}
354+
355+
/* Receive data. For QUAD_1_1_4 mode this starts later due to HW issue described above. */
356+
for (; iter < hrt_xfer_params->xfer_data[HRT_FE_DATA].word_count; iter++) {
357+
hrt_xfer_params->xfer_data[HRT_FE_DATA].data[iter] =
358+
nrf_vpr_csr_vio_in_buffered_reversed_byte_get() >> FOURTH_BYTE_SHIFT_CNT;
320359
}
321360

322361
/* Stop counters */
@@ -336,7 +375,18 @@ void hrt_read(volatile hrt_xfer_t *hrt_xfer_params)
336375
}
337376
}
338377

339-
/* Set DQ1 back as output. */
340-
WRITE_BIT(hrt_xfer_params->tx_direction_mask, SPI_INPUT_PIN_NUM, VPRCSR_NORDIC_DIR_OUTPUT);
341-
nrf_vpr_csr_vio_dir_set(hrt_xfer_params->tx_direction_mask);
378+
/* Copy the first 4 bytes of data to buffer. */
379+
if (hrt_xfer_params->bus_widths.address != hrt_xfer_params->bus_widths.data) {
380+
hrt_xfer_params->xfer_data[HRT_FE_DATA].data[0] = rec_data;
381+
hrt_xfer_params->xfer_data[HRT_FE_DATA].data[1] = rec_data >> SECOND_BYTE_SHIFT_CNT;
382+
hrt_xfer_params->xfer_data[HRT_FE_DATA].data[2] = rec_data >> THIRD_BYTE_SHIFT_CNT;
383+
hrt_xfer_params->xfer_data[HRT_FE_DATA].data[3] = rec_data >> FOURTH_BYTE_SHIFT_CNT;
384+
}
385+
386+
/* Set DQ1 back as output in SINGLE mode. */
387+
if (hrt_xfer_params->bus_widths.data == 1) {
388+
WRITE_BIT(hrt_xfer_params->tx_direction_mask, SPI_INPUT_PIN_NUM,
389+
VPRCSR_NORDIC_DIR_OUTPUT);
390+
nrf_vpr_csr_vio_dir_set(hrt_xfer_params->tx_direction_mask);
391+
}
342392
}

applications/sdp/mspi/src/main.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,6 @@ static void configure_clock(enum mspi_cpp_mode cpp_mode)
162162
}
163163
}
164164

165-
WRITE_BIT(out, 3, VPRCSR_NORDIC_OUT_HIGH);
166-
WRITE_BIT(out, 4, VPRCSR_NORDIC_OUT_HIGH);
167-
168165
nrf_vpr_csr_vio_out_set(out);
169166
nrf_vpr_csr_vio_config_set(&vio_config);
170167
}
@@ -398,6 +395,14 @@ static void ep_recv(const void *data, size_t len, void *priv)
398395
BIT(ce_vios[nrfe_mspi_devices[dev_config->device_index].ce_index]));
399396
}
400397

398+
if (dev_config->dev_config.io_mode == MSPI_IO_MODE_SINGLE) {
399+
nrf_vpr_csr_vio_out_or_set(BIT(3));
400+
nrf_vpr_csr_vio_out_or_set(BIT(4));
401+
} else {
402+
nrf_vpr_csr_vio_out_clear_set(BIT(3));
403+
nrf_vpr_csr_vio_out_clear_set(BIT(4));
404+
}
405+
401406
break;
402407
}
403408
case NRFE_MSPI_CONFIG_XFER: {

0 commit comments

Comments
 (0)