mirror of
https://github.com/apache/nuttx.git
synced 2026-10-07 22:35:22 +00:00
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 <marco.casaroli@gmail.com>
This commit is contained in:
parent
860577d771
commit
ed71eb7bc2
1 changed files with 40 additions and 5 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue