Simulated SPI RAM on RP2040
RP2040上的模拟SPI RAM
An SPI RAM implementation for RP2040.
RP2040的SPI RAM实施。
This project allows the RP2040 to act as if it were an serial SPI RAM, similar to a 23LC512.
该项目允许RP2040的作用,好像是串行SPI RAM,类似于23LC512。
The commands READ (0x03), WRITE (0x02) and FAST READ (0x0B) are implented. The RAM operates in sequential mode, and operations must not go beyond the end of the RAM.
命令读取(0x03),写入(0x02)和快速读取(0x0b)。RAM以顺序模式运行,并且操作不得超出RAM的末端。
Only SPI mode is supported (no DSPI/QSPI).
仅支持SPI模式(无DSPI/QSPI)。
The maximum clock rate supported depends on the system clock speed and the operation:
支持的最大时钟速率取决于系统时钟速度和操作:
Operation Max speed Max speed at 125MHz SYS clock READ SYS clock / 10 12.5 MHz READ (aligned) SYS clock / 8 15.6 MHz FAST READ SYS clock / 8 15.6 MHz WRITE SYS clock / 6 20.8 MHz
操作最大速度最大速度在125MHz sys时钟读取系统时钟 / 10 12.5 MHz读取(对齐)sys时钟 / 8 15.6 MHz快速读取系统时钟 / 8 15.6 MHz写入系统时钟 / 6 20.8 MHz
A READ is considered to be aligned if the start address is a multiple of 4. There is no requirement for the length of an aligned read to be a multiple of 4 bytes.
如果启动地址为4的倍数,则认为读取被认为是对齐的。对对齐的读数的长度不需要是4个字节的倍数。
Command details
命令详细信息
The SPI slave works in SPI mode 0 or 3 - data is transferred in both directions on the rising edge of SCK. All and addresses are transferred MSB first.
SPI从SPI模式0或3-数据在SCK的上升边缘上的两个方向都传输。所有和地址首先转移MSB。
READ
读
A read command is the byte 0x03 followed by a 16-bit address, MSB first. Data transfer begins immediately with no delay cycles. There is no limit to the length of the read, except that it may not go beyond the end of the RAM. The read is terminated by stopping the SCK and raising CS.
读取命令是字节0x03,然后是16位地址,MSB。数据传输立即开始,没有延迟周期。读取的长度没有限制,只是它可能不会超出RAM的末端。读取是通过停止SCK并提高CS来终止的。
FAST READ
快速阅读
A fast read command is the byte 0x0B followed by a 16-bit address, MSB first. There are then 8 delay cycles (one dummy byte transfer) before data transfer begins. Otherwise it is the same as a READ, except it might work at a faster clock rate.
快速读取命令是字节0x0b,然后是16位地址,MSB。然后,在数据传输开始之前,有8个延迟周期(一个虚拟字节传输)。否则,它与读取相同,只是它可能以更快的时钟速率工作。
WRITE
写
A write command is the byte 0x02 followed by a 16-bit address, MSB first. The data to be written to that address follows immediately. There is no limit to the length of the write, except that it may not go beyond the end of the RAM. The read is terminated by stopping the SCK and raising CS.
写命令是字节0x02,然后是16位地址,MSB。将要写入该地址的数据立即随之而来。写作的长度没有限制,只是它可能不会超出RAM的末端。读取是通过停止SCK并提高CS来终止的。
Using in your own project
在您自己的项目中使用
It is easiest to integrate by copying the 4 files beginning sram from this project into your project. Alternatively, you could include this project as a submodule.
通过将该项目从SRAM启动的4个文件复制到您的项目中,最容易集成。另外,您可以将此项目包括在内。
You will need to include the sram.c file in your source files, and add
您需要在源文件中包含sram.c文件,然后添加
pico_generate_pio_header(${NAME} ${CMAKE_CURRENT_LIST_DIR}/sram.pio) set_target_properties(${NAME} PROPERTIES PICO_TARGET_LINKER_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/sram_memmap.ld) pico_add_link_depend(${NAME} ${CMAKE_CURRENT_LIST_DIR}/sram_memmap.ld)
pico_generate_pio_header($ {name} $ {cmake_current_list_dir}/sram.pio)set_target_properties($ {name} properties pico_target_linker_linker_linker_script $PICO_ADD_LINK_DEPERAD
to your CMakeLists.txt to use a custom memory map that reserves the 64kB memory region for the RAM.
向您的cmakelists.txt使用自定义内存映射,该映射为RAM保留64KB内存区域。
Configure the pins, and if necessary DMA channels and PIO SMs by editing sram.h .
通过编辑SRAM.H来配置引脚,并在必要时进行DMA通道和PIO SMS。
Start the RAM by including sram.h and calling setup_simulated_sram() . This sets up the PIOs and launches the handler on core1.
通过包括sram.h并调用setup_simulation_sram()来启动RAM。这设置了PIO并在Core1上启动处理程序。
Note that in order to meet the strict timing requirements, the RAM simulation must have dedicated use of core1, and it uses most of the PIO instructions on both PIOs, though there are still a few instructions spare.
请注意,为了满足严格的计时要求,RAM模拟必须专门使用Core1,并且它在两个pios上使用了大多数PIO说明,尽管仍然有一些说明。
How it works
它如何工作
To meet the tight timing as much is done with PIO and DMA as possible. There are separate PIO programs handling data in and data out. The basic flow is:
要满足紧密的时机,请尽可能多地完成PIO和DMA。有单独的PIO程序处理数据和数据。基本流量是:
Both PIOs wait for CS to go low
两个pio都在等待CS降低
The read PIO reads the first byte and sends it up to core1, which does the appropriate setup for the command while the address is being received
读取PIO读取第一个字节并将其发送到core1,在接收地址时为命令进行适当的设置
The read PIO reads all but the last 2 bits of the address. This is handled on core1 or DMA directly, depending on the command.
读取的PIO读取了地址的最后2位。这是直接在core1或dma上处理的,具体取决于命令。
The read PIO reads the last 2 bits of the address. This is handled on core1 or ignored, depending on the command. Simultaneously the write PIO branches depending on the value of the last 2 bits so that it can discard the right amount of data from the first 32-bit word for unaligned READ comands.
读取PIO读取地址的最后两个位。根据命令,这是在Core1上处理或忽略的。同时根据最后2位的值,写入PIO分支,以便它可以从第一个32位单词中丢弃适量的数据,以获取未对齐的读取comands。
Data is then transferred in or out by the appropriate PIO.
然后,数据由适当的PIO输入或输出。
All processing on the CPU is handled by core1, interrupts are not used so there is no overhead going into and out of interrupt contexts, instead the core is always waiting for what it is expecting to happen next. The core1 program is loaded into a dedicated scratch RAM bank so there is no contention with general RAM access, to ensure that the execution timings are very consistent.
CPU上的所有处理均由Core1处理,不使用中断,因此没有开销的开销和中断上下文,而是核心总是在等待下一步发生的事情。将Core1程序加载到专用的Scratch RAM银行中,因此与常规RAM访问没有争议,以确保执行时间非常一致。
Core1 is always used to detect CS going high, terminating the transaction. It then aborts the DMA transfer and resets the PIOs ready for the next command.
CORE1始终用于检测CS高,从而终止了交易。然后,它退出DMA转移,然后将pios重置为下一个命令。
READ
读
The hardest timing is for the READ instruction, where the data must be available immediately the next cycle after the end of the address. To acheive this:
最难的时机是用于读取指令,在地址结束后必须在下一个周期立即提供数据。为了获得这一点:
The memory representing the SRAM is at a fixed location in the RP2040s address space ( 0x20030000 ), and the 0x2003 is prepended to the received address by the read PIO.
代表SRAM的内存位于RP2040S地址空间(0x20030000)中的固定位置,并且0x2003由Read Pio预先到达地址。
), and the is prepended to the received address by the read PIO. Once first 14 bits of the address are read, the address is padded with 2 0s to make it complete, and DMA'd to the read address trigger register of the transmit DMA channel, to be sent to the write PIO.
),然后由Read Pio添加到收到的地址。一旦读取了地址的前14位,地址将用2 0s填充以使其完成,并将DMA'D读取到发送DMA通道的读取地址触发器寄存器,并将发送到Write PIO。
The DMA will send 32-bit words at a time to the write PIO.
DMA将一次向写PIO发送32位单词。
The write PIO reads the last 2 bits of the address using the jmp pin instruction, selecting a branch that will discard an appropriate amount of data from the beginning of the data transferred to it.
Write PIO使用JMP PIN指令读取地址的最后两个位,选择一个分支,该分支将从传输到其的数据的开头中丢弃适当数量的数据。
instruction, selecting a branch that will discard an appropriate amount of data from the beginning of the data transferred to it. Once this is done the write PIO sends the data a bit at a time until the transfer is aborted.
指令,选择一个将从传输到其的数据开头丢弃适当数量数据的分支。完成此操作后,写PIO一次发送数据,直到传输中止。
WRITE
写
Relatively speaking, this is simple:
相对而言,这很简单:
The first 14 and last 2 bits of the address are combined on core1, which then triggers a DMA channel to read the data from the read PIO into memory.
地址的前14位和最后两个位是在Core1上组合的,然后触发DMA通道以将读取PIO的数据读取到内存中。
The read PIO transfers receives the data a byte at a time until the transfer is aborted.
读取PIO传输一次接收数据字节,直到传输中止。
FAST READ
快速阅读
A FAST READ command has dummy cycles to allow the address to be processed by the RAM before data needs to be sent. Because everything is optimized for standard READ commands, FAST READ is implemented as a bit of a hack:
快速读取命令具有虚拟周期,可以在需要发送数据之前由RAM处理该地址。由于所有内容都是针对标准读取命令进行了优化的,因此快速读取被实现为一个黑客:
On receiving the command, core1 patches the write PIO program to jump to an additional delay loop after the first 14 bits of the address, instead of branching on the last 2 bits.
接收命令后,Core1修补了Write Pio程序,以在地址的前14位之后跳至附加延迟循环,而不是在最后2位分支。
The DMA and write PIO autopull are reconfigured to transfer a byte at a time (because the DMA start address might not be aligned)
DMA和Write Pio Autopull一次重新配置以一次传输字节(因为DMA启动地址可能无法对齐)
The DMA is started (using the combined address) ready for the transfer to begin.
DMA启动(使用组合地址)准备转移开始。
After the transfer is aborted, the write PIO and DMA are reset to the values required for a READ command.
传输中止后,写入PIO和DMA将重置为读取命令所需的值。
Limitations / Bugs
限制 /错误
Currently the time that CS must be high between operations is uncharacterised, but it is likely to be around 50 SYS clocks.
目前,CS在操作之间必须较高的时间尚未表征,但可能是50个系统时钟。
Aborting operations before the data transfer starts is not supported.
不支持数据传输启动之前中止操作。