-
Notifications
You must be signed in to change notification settings - Fork 0
/
dma.h
141 lines (120 loc) · 6.51 KB
/
dma.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#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