2021-01-27 08:18:51 +00:00

142 lines
6.5 KiB
C

#pragma once
#ifdef USE_DMA_TRANSFERS
#define BCM2835_DMA0_OFFSET 0x7000 // DMA channels 0-14 live at 0x7E007000, offset of 0x7000 of BCM2835 peripherals base address
#define BCM2835_DMAENABLE_REGISTER_OFFSET 0xff0
typedef struct __attribute__ ((packed, aligned(4))) DMAControlBlock
{
uint32_t ti;
uint32_t src;
uint32_t dst;
uint32_t len;
uint32_t stride;
uint32_t next;
uint32_t debug;
uint32_t reserved;
} DMAControlBlock;
typedef struct __attribute__ ((packed, aligned(4))) DMAChannelRegisterFile
{
volatile uint32_t cs;
volatile uint32_t cbAddr;
volatile DMAControlBlock cb;
volatile uint8_t padding[216]; // Pad this structure to 256 bytes in size total for easy indexing into DMA channels.
} DMAChannelRegisterFile;
extern int dmaTxChannel, dmaTxIrq;
extern volatile DMAChannelRegisterFile *dmaTx; // DMA channel allocated to sending to SPI
extern int dmaRxChannel, dmaRxIrq;
extern volatile DMAChannelRegisterFile *dmaRx; // DMA channel allocated to reading from SPI
volatile DMAChannelRegisterFile *GetDMAChannel(int channelNumber);
#define BCM2835_DMA_CS_RESET (1<<31)
#define BCM2835_DMA_CS_ABORT (1<<30)
#define BCM2835_DMA_CS_DISDEBUG (1<<29)
#define BCM2835_DMA_CS_WAIT_FOR_OUTSTANDING_WRITES (1<<28)
#define BCM2835_DMA_CS_PANIC_PRIORITY (0xF<<20)
#define BCM2835_DMA_CS_PRIORITY (0xF<<16)
#define BCM2835_DMA_CS_ERROR (1<<8)
#define BCM2835_DMA_CS_WAITING_FOR_OUTSTANDING_WRITES (1<<6)
#define BCM2835_DMA_CS_DREQ_STOPS_DMA (1<<5)
#define BCM2835_DMA_CS_PAUSED (1<<4)
#define BCM2835_DMA_CS_DREQ (1<<3)
#define BCM2835_DMA_CS_INT (1<<2)
#define BCM2835_DMA_CS_END (1<<1)
#define BCM2835_DMA_CS_ACTIVE (1<<0)
#define BCM2835_DMA_CS_SET_PANIC_PRIORITY(p) ((p) << 20)
#define BCM2835_DMA_CS_SET_PRIORITY(p) ((p) << 16)
#define BCM2835_DMA_CS_RESET_SHIFT 31
#define BCM2835_DMA_CS_ABORT_SHIFT 30
#define BCM2835_DMA_CS_DISDEBUG_SHIFT 29
#define BCM2835_DMA_CS_WAIT_FOR_OUTSTANDING_WRITES_SHIFT 28
#define BCM2835_DMA_CS_PANIC_PRIORITY_SHIFT 20
#define BCM2835_DMA_CS_PRIORITY_SHIFT 16
#define BCM2835_DMA_CS_ERROR_SHIFT 8
#define BCM2835_DMA_CS_WAITING_FOR_OUTSTANDING_WRITES_SHIFT 6
#define BCM2835_DMA_CS_DREQ_STOPS_DMA_SHIFT 5
#define BCM2835_DMA_CS_PAUSED_SHIFT 4
#define BCM2835_DMA_CS_DREQ_SHIFT 3
#define BCM2835_DMA_CS_INT_SHIFT 2
#define BCM2835_DMA_CS_END_SHIFT 1
#define BCM2835_DMA_CS_ACTIVE_SHIFT 0
#define BCM2835_DMA_DEBUG_LITE (1<<28)
#define BCM2835_DMA_DEBUG_VERSION (7<<25)
#define BCM2835_DMA_DEBUG_DMA_STATE (0x1FF<<16)
#define BCM2835_DMA_DEBUG_DMA_ID (0xFF<<8)
#define BCM2835_DMA_DEBUG_DMA_OUTSTANDING_WRITES (0xF<<4)
#define BCM2835_DMA_DEBUG_DMA_READ_ERROR (1<<2)
#define BCM2835_DMA_DEBUG_DMA_FIFO_ERROR (1<<1)
#define BCM2835_DMA_DEBUG_READ_LAST_NOT_SET_ERROR (1<<0)
#define BCM2835_DMA_DEBUG_LITE_SHIFT 28
#define BCM2835_DMA_DEBUG_VERSION_SHIFT 25
#define BCM2835_DMA_DEBUG_DMA_STATE_SHIFT 16
#define BCM2835_DMA_DEBUG_DMA_ID_SHIFT 8
#define BCM2835_DMA_DEBUG_DMA_OUTSTANDING_WRITES_SHIFT 4
#define BCM2835_DMA_DEBUG_DMA_READ_ERROR_SHIFT 2
#define BCM2835_DMA_DEBUG_DMA_FIFO_ERROR_SHIFT 1
#define BCM2835_DMA_DEBUG_READ_LAST_NOT_SET_ERROR_SHIFT 0
#define BCM2835_DMA_TI_NO_WIDE_BURSTS (1<<26)
#define BCM2835_DMA_TI_WAITS (0x1F<<21)
#define BCM2835_DMA_TI_PERMAP(x) ((x)<<16)
#define BCM2835_DMA_TI_PERMAP_MASK (0x1F<<16)
#define BCM2835_DMA_TI_PERMAP_SPI_TX 6
#define BCM2835_DMA_TI_PERMAP_SPI_RX 7
#define BCM2835_DMA_TI_BURST_LENGTH(x) ((x)<<12)
#define BCM2835_DMA_TI_SRC_IGNORE (1<<11)
#define BCM2835_DMA_TI_SRC_DREQ (1<<10)
#define BCM2835_DMA_TI_SRC_WIDTH (1<<9)
#define BCM2835_DMA_TI_SRC_INC (1<<8)
#define BCM2835_DMA_TI_DEST_IGNORE (1<<7)
#define BCM2835_DMA_TI_DEST_DREQ (1<<6)
#define BCM2835_DMA_TI_DEST_WIDTH (1<<5)
#define BCM2835_DMA_TI_DEST_INC (1<<4)
#define BCM2835_DMA_TI_WAIT_RESP (1<<3)
#define BCM2835_DMA_TI_TDMODE (1<<1)
#define BCM2835_DMA_TI_INTEN (1<<0)
#define BCM2835_DMA_TI_NO_WIDE_BURSTS_SHIFT 26
#define BCM2835_DMA_TI_WAITS_SHIFT 21
#define BCM2835_DMA_TI_PERMAP_SHIFT 16
#define BCM2835_DMA_TI_BURST_LENGTH_SHIFT 12
#define BCM2835_DMA_TI_SRC_IGNORE_SHIFT 11
#define BCM2835_DMA_TI_SRC_DREQ_SHIFT 10
#define BCM2835_DMA_TI_SRC_WIDTH_SHIFT 9
#define BCM2835_DMA_TI_SRC_INC_SHIFT 8
#define BCM2835_DMA_TI_DEST_IGNORE_SHIFT 7
#define BCM2835_DMA_TI_DEST_DREQ_SHIFT 6
#define BCM2835_DMA_TI_DEST_WIDTH_SHIFT 5
#define BCM2835_DMA_TI_DEST_INC_SHIFT 4
#define BCM2835_DMA_TI_WAIT_RESP_SHIFT 3
#define BCM2835_DMA_TI_TDMODE_SHIFT 1
#define BCM2835_DMA_TI_INTEN_SHIFT 0
// Spec sheet says there's 16 channels, but last channel is unusable:
// https://www.raspberrypi.org/forums/viewtopic.php?t=170957
// So just behave as if there are only 15 channels
#define BCM2835_NUM_DMA_CHANNELS 15
void WaitForDMAFinished(void);
// Reserves and enables a DMA channel for SPI transfers.
int InitDMA(void);
void DeinitDMA(void);
typedef struct SPITask SPITask;
void SPIDMATransfer(SPITask *task);
extern int dmaTxChannel;
extern int dmaRxChannel;
extern uint64_t totalGpuMemoryUsed;
#endif