This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit ed71eb7bc296784c109b78b9d8e3594080b0d816
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Oct 7 09:06:12 2026 +0200

    arch/arm/rp23xx: Compute the PSRAM QMI timing from the system clock.
    
    RP23XX_PSRAM_M1_TIMING was the constant 0x61a07102.  The comment said
    it matched the Pico SDK, but it does not.  The SDK computes the timing
    from clk_sys and the APS6404 limits (133 MHz SCK, 8 us maximum select,
    18 ns minimum deselect).  At 150 MHz it gives 0x60242202:
    
      field         old  SDK
      clkdiv        2    2
      rxdelay       1    2
      max_select    16   18
      min_deselect  7    2
      select_hold   3    0
    
    The old RX delay samples the read data half a clk_sys cycle earlier
    than the SDK does.  The constant is also wrong for any other clk_sys.
    
    Compute the fields from BOARD_SYS_FREQ at build time, with the SDK
    formula, and stop the build if a field is out of range.  The result
    is identical to the SDK value at 48, 125, 150, 200, 266 and 300 MHz.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/arm/src/rp23xx/rp23xx_psram.c | 45 +++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/arch/arm/src/rp23xx/rp23xx_psram.c 
b/arch/arm/src/rp23xx/rp23xx_psram.c
index 9aa6837c8f8..1acc2a2e546 100644
--- a/arch/arm/src/rp23xx/rp23xx_psram.c
+++ b/arch/arm/src/rp23xx/rp23xx_psram.c
@@ -44,6 +44,8 @@
 
 #include <nuttx/irq.h>
 
+#include <arch/board/board.h>
+
 #include "arm_internal.h"
 #include "rp23xx_gpio.h"
 #include "rp23xx_psram.h"
@@ -73,18 +75,51 @@
 
 #define QMI_DIRECT_TX_IWIDTH_Q    (2 << RP23XX_QMI_DIRECT_TX_IWIDTH_SHIFT)
 
-/* Final QMI M1 register values for the APS6404 in quad mode.  Computed from
- * the field layout in the RP2350 datasheet to match the Pico SDK:
+/* APS6404 limits, as in the Pico SDK: 133 MHz SCK, 8 us maximum chip
+ * select time (refresh), 18 ns minimum deselect time.
+ */
+
+#define PSRAM_MAX_FREQ            133000000
+#define PSRAM_MAX_SELECT_NS       8000ull
+#define PSRAM_MIN_DESELECT_NS     18ull
+
+/* QMI M1 timing for clk_sys, computed as the Pico SDK does.  Do not use a
+ * divisor of 1 above 100 MHz, and add one RX delay step above 100 MHz SCK.
+ */
+
+#define PSRAM_CLKDIV_MIN \
+  ((BOARD_SYS_FREQ + PSRAM_MAX_FREQ - 1) / PSRAM_MAX_FREQ)
+#define PSRAM_CLKDIV \
+  (PSRAM_CLKDIV_MIN == 1 && BOARD_SYS_FREQ > 100000000 ? 2 : PSRAM_CLKDIV_MIN)
+#define PSRAM_RXDELAY \
+  (PSRAM_CLKDIV + (BOARD_SYS_FREQ / PSRAM_CLKDIV > 100000000 ? 1 : 0))
+#define PSRAM_MAX_SELECT \
+  (PSRAM_MAX_SELECT_NS * BOARD_SYS_FREQ / (64 * 1000000000ull))
+#define PSRAM_MIN_DESELECT \
+  ((PSRAM_MIN_DESELECT_NS * BOARD_SYS_FREQ + 999999999) / 1000000000 - \
+   (PSRAM_CLKDIV + 1) / 2)
+
+#if PSRAM_CLKDIV > 255 || PSRAM_RXDELAY > 7 || PSRAM_MAX_SELECT > 63 || \
+    PSRAM_MIN_DESELECT > 31
+#  error "BOARD_SYS_FREQ is out of range for the PSRAM timing"
+#endif
+
+/* Final QMI M1 register values for the APS6404 in quad mode:
  *
- * TIMING: COOLDOWN=1, PAGEBREAK=1024, SELECT_HOLD=3, MAX_SELECT=16,
- *         MIN_DESELECT=7, RXDELAY=1, CLKDIV=2.
+ * TIMING: COOLDOWN=1, PAGEBREAK=1024, and the values above.
  * RFMT:   quad prefix/addr/suffix/dummy/data, 8-bit prefix, 24 dummy bits.
  * RCMD:   read prefix 0xeb.
  * WFMT:   quad prefix/addr/suffix/dummy/data, 8-bit prefix, no dummy.
  * WCMD:   write prefix 0x38.
  */
 
-#define RP23XX_PSRAM_M1_TIMING    0x61a07102
+#define RP23XX_PSRAM_M1_TIMING \
+  ((1 << RP23XX_QMI_TIMING_COOLDOWN_SHIFT) | \
+   (2 << RP23XX_QMI_TIMING_PAGEBREAK_SHIFT) | \
+   ((uint32_t)PSRAM_MAX_SELECT << RP23XX_QMI_TIMING_MAX_SELECT_SHIFT) | \
+   ((uint32_t)PSRAM_MIN_DESELECT << RP23XX_QMI_TIMING_MIN_DESELECT_SHIFT) | \
+   (PSRAM_RXDELAY << RP23XX_QMI_TIMING_RXDELAY_SHIFT) | \
+   PSRAM_CLKDIV)
 #define RP23XX_PSRAM_M1_RFMT      0x000612aa
 #define RP23XX_PSRAM_M1_RCMD      0x000000eb
 #define RP23XX_PSRAM_M1_WFMT      0x000012aa

Reply via email to