51#include "hardware/pio.h"
52#include "hardware/gpio.h"
53#include "hardware/timer.h"
54#include "hardware/dma.h"
55#if defined(PSRAM_MUTEX)
56#include "pico/mutex.h"
60#include "psram_spi.pio.h"
75#if defined(PSRAM_MUTEX)
79 dma_channel_config write_dma_chan_config;
81 dma_channel_config read_dma_chan_config;
83 dma_channel_config async_dma_chan_config;
105 const uint8_t* src,
const size_t src_len,
106 uint8_t* dst,
const size_t dst_len
108 size_t tx_remain = src_len, rx_remain = dst_len;
110#if defined(PSRAM_MUTEX)
111 mutex_enter_blocking(&spi->mtx);
113 io_rw_8 *txfifo = (io_rw_8 *) &spi->pio->txf[spi->sm];
115 if (!pio_sm_is_tx_fifo_full(spi->pio, spi->sm)) {
121 io_rw_8 *rxfifo = (io_rw_8 *) &spi->pio->rxf[spi->sm];
123 if (!pio_sm_is_rx_fifo_empty(spi->pio, spi->sm)) {
129#if defined(PSRAM_MUTEX)
130 mutex_exit(&spi->mtx);
148 const uint8_t* src,
const size_t src_len
151 mutex_enter_blocking(&spi->mtx);
153 dma_channel_transfer_from_buffer_now(spi->write_dma_chan, src, src_len);
154 dma_channel_wait_for_finish_blocking(spi->write_dma_chan);
156 mutex_exit(&spi->mtx);
178 const uint8_t* src,
const size_t src_len,
179 uint8_t* dst,
const size_t dst_len
182 mutex_enter_blocking(&spi->mtx);
184 dma_channel_transfer_from_buffer_now(spi->write_dma_chan, src, src_len);
185 dma_channel_transfer_to_buffer_now(spi->read_dma_chan, dst, dst_len);
186 dma_channel_wait_for_finish_blocking(spi->write_dma_chan);
187 dma_channel_wait_for_finish_blocking(spi->read_dma_chan);
189 mutex_exit(&spi->mtx);
194void __isr dma_complete_handler() {
195 dma_hw->ints1 = 1u << async_spi_inst->async_dma_chan;
197 mutex_exit(&async_spi_inst->mtx);
214 const uint8_t* src,
const size_t src_len
217 mutex_enter_blocking(&spi->mtx);
220 dma_channel_wait_for_finish_blocking(spi->async_dma_chan);
221 async_spi_inst = spi;
223 dma_channel_transfer_from_buffer_now(spi->async_dma_chan, src, src_len);
235 uint spi_offset = pio_add_program(pio1, &spi_fudge_program);
236 uint spi_sm = pio_claim_unused_sm(pio1,
true);
240#if defined(PSRAM_MUTEX)
241 mutex_init(&spi.mtx);
244 gpio_set_drive_strength(PSRAM_PIN_CS, GPIO_DRIVE_STRENGTH_2MA);
245 gpio_set_drive_strength(PSRAM_PIN_SCK, GPIO_DRIVE_STRENGTH_2MA);
246 gpio_set_drive_strength(PSRAM_PIN_MOSI, GPIO_DRIVE_STRENGTH_2MA);
247 gpio_set_slew_rate(PSRAM_PIN_CS, GPIO_SLEW_RATE_FAST);
248 gpio_set_slew_rate(PSRAM_PIN_SCK, GPIO_SLEW_RATE_FAST);
249 gpio_set_slew_rate(PSRAM_PIN_MOSI, GPIO_SLEW_RATE_FAST);
251 pio_spi_fudge_cs_init(pio1, spi_sm, spi_offset, 8 , 1 , PSRAM_PIN_CS, PSRAM_PIN_MOSI, PSRAM_PIN_MISO);
254 spi.write_dma_chan = dma_claim_unused_channel(
true);
255 spi.write_dma_chan_config = dma_channel_get_default_config(spi.write_dma_chan);
256 channel_config_set_transfer_data_size(&spi.write_dma_chan_config, DMA_SIZE_8);
257 channel_config_set_read_increment(&spi.write_dma_chan_config,
true);
258 channel_config_set_write_increment(&spi.write_dma_chan_config,
false);
259 channel_config_set_dreq(&spi.write_dma_chan_config, pio_get_dreq(spi.pio, spi.sm,
true));
260 dma_channel_set_write_addr(spi.write_dma_chan, &spi.pio->txf[spi.sm],
false);
261 dma_channel_set_config(spi.write_dma_chan, &spi.write_dma_chan_config,
false);
264 spi.read_dma_chan = dma_claim_unused_channel(
true);
265 spi.read_dma_chan_config = dma_channel_get_default_config(spi.read_dma_chan);
266 channel_config_set_transfer_data_size(&spi.read_dma_chan_config, DMA_SIZE_8);
267 channel_config_set_read_increment(&spi.read_dma_chan_config,
false);
268 channel_config_set_write_increment(&spi.read_dma_chan_config,
true);
269 channel_config_set_dreq(&spi.read_dma_chan_config, pio_get_dreq(spi.pio, spi.sm,
false));
270 dma_channel_set_read_addr(spi.read_dma_chan, &spi.pio->rxf[spi.sm],
false);
271 dma_channel_set_config(spi.read_dma_chan, &spi.read_dma_chan_config,
false);
274 spi.async_dma_chan = dma_claim_unused_channel(
true);
275 spi.async_dma_chan_config = dma_channel_get_default_config(spi.async_dma_chan);
276 channel_config_set_transfer_data_size(&spi.async_dma_chan_config, DMA_SIZE_8);
277 channel_config_set_read_increment(&spi.async_dma_chan_config,
true);
278 channel_config_set_write_increment(&spi.async_dma_chan_config,
false);
279 channel_config_set_dreq(&spi.async_dma_chan_config, pio_get_dreq(spi.pio, spi.sm,
true));
280 dma_channel_set_write_addr(spi.async_dma_chan, &spi.pio->txf[spi.sm],
false);
281 dma_channel_set_config(spi.async_dma_chan, &spi.async_dma_chan_config,
false);
282 irq_set_exclusive_handler(DMA_IRQ_1, dma_complete_handler);
283 dma_irqn_set_channel_enabled(1, spi.async_dma_chan,
true);
284 irq_set_enabled(DMA_IRQ_1,
true);
286 uint8_t psram_reset_en_cmd[] = {
293 uint8_t psram_reset_cmd[] = {
305static uint8_t write8_command[] = {
324 write8_command[3] = addr >> 16;
325 write8_command[4] = addr >> 8;
326 write8_command[5] = addr;
327 write8_command[6] = val;
346 write8_command[3] = addr >> 16;
347 write8_command[4] = addr >> 8;
348 write8_command[5] = addr;
349 write8_command[6] = val;
355static uint8_t read8_command[] = {
375 read8_command[3] = addr >> 16;
376 read8_command[4] = addr >> 8;
377 read8_command[5] = addr;
385static uint8_t write16_command[] = {
405 write16_command[3] = addr >> 16;
406 write16_command[4] = addr >> 8;
407 write16_command[5] = addr;
408 write16_command[6] = val;
409 write16_command[7] = val >> 8;
415static uint8_t read16_command[] = {
435 read16_command[3] = addr >> 16;
436 read16_command[4] = addr >> 8;
437 read16_command[5] = addr;
445static uint8_t write32_command[] = {
466 write32_command[3] = addr >> 16;
467 write32_command[4] = addr >> 8;
468 write32_command[5] = addr;
469 write32_command[6] = val;
470 write32_command[7] = val >> 8;
471 write32_command[8] = val >> 16;
472 write32_command[9] = val >> 24;
478static uint8_t read32_command[] = {
498 read32_command[3] = addr >> 16;
499 read32_command[4] = addr >> 8;
500 read32_command[5] = addr;
508static uint8_t write_command[] = {
526 write_command[0] = (4 + count) * 8;
527 write_command[3] = addr >> 16;
528 write_command[4] = addr >> 8;
529 write_command[5] = addr;
536static uint8_t read_command[] = {
554 read_command[1] = count * 8;
555 read_command[3] = addr >> 16;
556 read_command[4] = addr >> 8;
557 read_command[5] = addr;
__force_inline void __time_critical_func() pio_spi_write_read_dma_blocking(psram_spi_inst_t *spi, const uint8_t *src, const size_t src_len, uint8_t *dst, const size_t dst_len)
Write and read raw data to the PSRAM SPI PIO, driven by DMA without CPU involvement.
Definition: psram_spi.h:176
__force_inline void __time_critical_func() pio_spi_write_read_blocking(psram_spi_inst_t *spi, const uint8_t *src, const size_t src_len, uint8_t *dst, const size_t dst_len)
Write and read raw data to the PSRAM SPI PIO, driven by the CPU without DMA. This can be used if DMA ...
Definition: psram_spi.h:103
__force_inline void __time_critical_func() pio_spi_write_dma_blocking(psram_spi_inst_t *spi, const uint8_t *src, const size_t src_len)
Write raw data to the PSRAM SPI PIO, driven by DMA without CPU involvement.
Definition: psram_spi.h:146
__force_inline uint16_t psram_read16(psram_spi_inst_t *spi, uint32_t addr)
Read 16 bits of data from a given address to the PSRAM SPI PIO, driven by DMA without CPU involvement...
Definition: psram_spi.h:434
__force_inline uint8_t psram_read8(psram_spi_inst_t *spi, uint32_t addr)
Read 8 bits of data from a given address to the PSRAM SPI PIO, driven by DMA without CPU involvement,...
Definition: psram_spi.h:374
__force_inline void psram_write8(psram_spi_inst_t *spi, uint32_t addr, uint8_t val)
Write 8 bits of data to a given address to the PSRAM SPI PIO, driven by DMA without CPU involvement,...
Definition: psram_spi.h:345
__force_inline void psram_write32(psram_spi_inst_t *spi, uint32_t addr, uint32_t val)
Write 32 bits of data to a given address to the PSRAM SPI PIO, driven by DMA without CPU involvement,...
Definition: psram_spi.h:464
__force_inline void psram_read(psram_spi_inst_t *spi, const uint32_t addr, uint8_t *dst, const size_t count)
Read count bits of data from a given address to the PSRAM SPI PIO, driven by DMA without CPU involvem...
Definition: psram_spi.h:553
__force_inline void psram_write(psram_spi_inst_t *spi, const uint32_t addr, const uint8_t *src, const size_t count)
Write count bytes of data to a given address to the PSRAM SPI PIO, driven by DMA without CPU involvem...
Definition: psram_spi.h:524
struct psram_spi_inst psram_spi_inst_t
A struct that holds the configuration for the PSRAM interface.
__force_inline void __time_critical_func() pio_spi_write_async(psram_spi_inst_t *spi, const uint8_t *src, const size_t src_len)
Write raw data asynchronously to the PSRAM SPI PIO, driven by DMA without CPU involvement.
Definition: psram_spi.h:212
psram_spi_inst_t psram_spi_init(void)
Initialize the PSRAM over SPI. This function must be called before accessing PSRAM.
Definition: psram_spi.h:234
__force_inline uint32_t psram_read32(psram_spi_inst_t *spi, uint32_t addr)
Read 32 bits of data from a given address to the PSRAM SPI PIO, driven by DMA without CPU involvement...
Definition: psram_spi.h:497
__force_inline void psram_write8_async(psram_spi_inst_t *spi, uint32_t addr, uint8_t val)
Write 8 bits of data to a given address asynchronously to the PSRAM SPI PIO, driven by DMA without CP...
Definition: psram_spi.h:323
__force_inline void psram_write16(psram_spi_inst_t *spi, uint32_t addr, uint16_t val)
Write 16 bits of data to a given address to the PSRAM SPI PIO, driven by DMA without CPU involvement,...
Definition: psram_spi.h:404
A struct that holds the configuration for the PSRAM interface.
Definition: psram_spi.h:72