11
11
* */
12
12
/* *******************************/
13
13
#ifndef FRAMES_PER_LINE
14
+ /* *
15
+ * The number of frames required to draw one line to the screen.
16
+ */
14
17
#define FRAMES_PER_LINE 16
15
18
#endif
16
19
#ifndef LINES_PER_DMA
20
+ /* *
21
+ * The number of lines to be created/filled before the transfer starts
22
+ */
17
23
#define LINES_PER_DMA 8
18
24
#endif
19
25
#ifndef WORKING_DATA_PER_LINE
26
+ /* *
27
+ * The number of bytes required to draw a line on the screen
28
+ */
20
29
#define WORKING_DATA_PER_LINE 19
21
30
#endif
22
31
23
32
#define LLI_MAX_FRAMES (FRAMES_PER_LINE * LINES_PER_DMA)
24
33
#define WORKING_DATA_SIZE (WORKING_DATA_PER_LINE * LINES_PER_DMA)
34
+ /* *
35
+ * The number of bytes needed to set the lower/upper bytes for one coordinate
36
+ */
25
37
#define COORD_BUF_SPACE 4
38
+ /* *
39
+ * How long to wait / buffer the CS pin low or high
40
+ */
26
41
#define DMA_CS_HIGH_TRANSFERS 8
27
42
28
43
// Forward Declaration for class
@@ -66,8 +81,14 @@ typedef union DMAFunctionData {
66
81
} DMAFunctionData;
67
82
68
83
typedef struct DMACallbackData {
84
+ /* *
85
+ * Data for use in the complete_cb function
86
+ */
69
87
void *dataPtr;
70
88
89
+ /* *
90
+ * Function called when transfers are complete
91
+ */
71
92
void (*complete_cb)(void *);
72
93
} DMACallbackData;
73
94
@@ -98,12 +119,19 @@ typedef struct DMA_Data {
98
119
99
120
void volatile (*on_complete)(SpiDriver *spiDriver);
100
121
101
-
122
+ /* *
123
+ * Resets the working data idx to 0. Doesn't actually clear data, just allows for overwrite
124
+ * @param full_clear Resets last_idx if true
125
+ */
102
126
inline void clear_working_data (bool full_clear = false ) {
103
127
last_storage_idx = full_clear ? 0 : storage_idx;
104
128
storage_idx = 0 ;
105
129
}
106
130
131
+ /* *
132
+ * Completely resets the DMA_Data instance
133
+ * @param full_reset Clears the last_data fields
134
+ */
107
135
inline void reset (bool full_reset = false ) {
108
136
clear_working_data (full_reset);
109
137
memset_volatile (&functionData, ' \0 ' , sizeof (DMAFunctionData));
@@ -116,10 +144,21 @@ typedef struct DMA_Data {
116
144
on_complete = nullptr ;
117
145
}
118
146
147
+ /* *
148
+ * @param size The amount of bytes needed to add
149
+ * @return true if there is space to add, false otherwise
150
+ */
119
151
inline bool can_add_working_data (size_t size) const {
120
152
return ((storage_idx - 1 ) + size) < WORKING_DATA_SIZE;
121
153
}
122
154
155
+ /* *
156
+ * Store sensitive data needed for DMA in a buffer for use during the transfers.
157
+ * Provides a size check to make sure the data can be added.
158
+ * @param buf The data to store
159
+ * @param size The number of bytes being added.
160
+ * @return uint8_t ptr to the location of the added data in the permanent buffer for future access.
161
+ */
123
162
inline volatile uint8_t *add_working_data (const uint8_t *buf, size_t size) {
124
163
if (!can_add_working_data (size)) {
125
164
return nullptr ;
@@ -165,6 +204,12 @@ class DMAManager {
165
204
166
205
volatile LLI *get_next_blank_entry ();
167
206
207
+ /* *
208
+ * Gets an entry from the chain
209
+ * @param idx The idx to get.
210
+ * @param force If the index is out of 'size' bounds, will return nullptr unless force is true. Will return the index from the array
211
+ * @return The entry, if within range (or if force specified). Nullptr otherwise.
212
+ */
168
213
volatile LLI *get_entry (size_t idx, bool force = false );
169
214
170
215
inline volatile LLI *get_last () {
@@ -179,16 +224,28 @@ class DMAManager {
179
224
* until we're done with the entire chain. This way if an element needs to be removed, all the `next` pointers won't need to be
180
225
* rewritten.
181
226
* This must be called before passing the beginning entry to DMA
227
+ * @return Ptr to the head of the list
182
228
*/
183
229
volatile LLI *finalize ();
184
230
231
+ /* *
232
+ * Resets the size counter, does not zero memory
233
+ */
185
234
void clear_frames ();
186
235
236
+ /* *
237
+ * Resets frames & working data
238
+ * @param full Clears the 'last_data' fields, if true
239
+ */
187
240
void reset (bool full = false );
188
241
189
242
size_t get_size () const ;
190
243
191
- bool can_add_entries (uint32_t entries) const ;
244
+ /* *
245
+ * @param entries The number of entries to check if available
246
+ * @return True if space, false otherwise
247
+ */
248
+ bool can_add_entries (size_t entries) const ;
192
249
193
250
DMA_Data *get_cur_data () {
194
251
return &transaction_data;
@@ -197,18 +254,55 @@ class DMAManager {
197
254
/* ***********************
198
255
* General purpose methods for adding SPI Frames, PIO Frames, etc.
199
256
************************/
257
+
258
+ /* *
259
+ * @param state The state of the pin (Returns SODR for true, CODR for false)
260
+ * @param pin The pin to get the register for
261
+ * @return The address for the register.
262
+ */
200
263
WoReg *get_pio_reg (bool state, uint8_t pin);
201
264
265
+ /* *
266
+ * Gets the register for the chipselect pin
267
+ * @param state The state for the pin
268
+ * @return The address for the register
269
+ */
202
270
WoReg *get_cs_pio_reg (bool state) {
203
271
return get_pio_reg (state, _csPin);
204
272
}
205
273
274
+ /* *
275
+ * Adds an entry to toggle a pin high or low
276
+ * @param state The new state of the pin
277
+ * @param pin The pin number
278
+ * @param pin_mask_ptr A pointer to somewhere with the mask for that pin. The g_APinDescriptor will not work for this purpose.
279
+ * @param num_transfers How many transfers to send.
280
+ * @return Whether or not the entry was added to the buffer
281
+ */
206
282
bool add_entry_pin_toggle (bool state, uint8_t pin, const uint32_t *pin_mask_ptr, size_t num_transfers = 2 );
207
283
284
+ /* *
285
+ * Specifically adds an entry to toggle the CS pin
286
+ * @param state The new state for the pin
287
+ * @param num_transfers How many transfers to send. The RA chip requires that CS be high for ~5 CLK cycles before going low again.
288
+ * @return Whether or not the entry was added to the buffer.
289
+ */
208
290
bool add_entry_cs_pin_toggle (bool state, size_t num_transfers = 2 );
209
291
292
+ /* *
293
+ * Adds a generic SPI transfer to the list
294
+ * @param buf The start of the data to transfer.
295
+ * @param qty The number of bytes in the buffer.
296
+ * @return Whether or not the entry was added to the list
297
+ */
210
298
bool add_entry_spi_transfer (volatile uint8_t *buf, size_t qty);
211
299
300
+ /* *
301
+ * Adds all the necessary entries to draw a batch of pixels in an area.
302
+ * @param buf The buffer of pixels to add
303
+ * @param qty The number of pixels drawn
304
+ * @return uint8_t ptr to the start of the working data containing the draw commands (RA8875_CMDWRITE, DATAWRITE, etc)
305
+ */
212
306
volatile uint8_t *add_entry_spi_draw_pixels (volatile uint8_t *buf, size_t qty);
213
307
214
308
/* *
0 commit comments