forked from till-s/rtems-drv-coldfire-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
coldfUtils.h
428 lines (364 loc) · 13 KB
/
coldfUtils.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
/* $Id$ */
/* Support for several arcturus / coldfire features */
#ifndef COLDFIRE_5282_UTILS_H
#define COLDFIRE_5282_UTILS_H
#include <rtems.h>
#include <mcf5282/mcf5282.h>
#include <stdint.h>
/* Hmm __IPSBAR is defined in the linker script :-( */
#ifndef __IPSBAR
#define __IPSBAR ((volatile uint8_t *)0x40000000)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ============== EPORT ============== */
/* EPORT interrupts, pin configuration & the like */
/* EPORT setup */
#define EPORT_OUTPUT (-1)
#define EPORT_LEVEL (0)
#define EPORT_RAISING (1)
#define EPORT_FALLING (2)
#define EPORT_BOTH (3)
int
coldfEportSetup(int pin, int config);
/* enable/disable interrupts; pin must be 1..7 [not checked] */
static inline void
coldfEportIntEnable_inl(int pin)
{
int level;
rtems_interrupt_disable(level);
MCF5282_EPORT_EPIER |= (MCF5282_EPORT_EPIER_EPIE(pin));
rtems_interrupt_enable(level);
}
static inline int
coldfEportIntDisable_inl(int pin)
{
int level;
int rval;
rtems_interrupt_disable(level);
rval = (MCF5282_EPORT_EPIER & (MCF5282_EPORT_EPIER_EPIE(pin)));
MCF5282_EPORT_EPIER &= ~(MCF5282_EPORT_EPIER_EPIE(pin));
rtems_interrupt_enable(level);
return rval;
}
/* extern versions [pin = 1..7] */
void
coldfEportIntEnable(int pin);
/* Disable interrupt and return previous status of mask */
int
coldfEportIntDisable(int pin);
/* Toggle a bit [pin = 1..7] */
int
coldfEportEpdrToggle(int bit);
/* Set or clear a bit. If 'bit' is zero then all bits
* in 'value' are written to the EPORT.
*/
int
coldfEportEpdrSet(int bit, unsigned value);
/* Read current status of pin; if pin==0 all bits are read */
int
coldfEportEppdrGet(int pin);
/* Get flag register bit; if pin == 0 all bits are returned */
int
coldfEportFlagGet(int pin);
/* Clear flag register bit (returns pre-clear status); if pin == 0 all bits are cleared / returned */
int
coldfEportFlagClr(int pin);
/* =============== IRQ =============== */
/* A simple ISR that can be used for testing
* (install/remove using BSP_installVME_isr(vector, isr, uarg)
* It prints the user arg and vector number to
* the console and disables the interrupt at the controller
* (user BSP_enable_irq_at_pic() to re-enable).
*/
void
coldfTestISR(void *uarg, unsigned long vector);
/* =============== DMA =============== */
/*
* DMA Transfer : WARNING -- this is work in progress and the API might change
*/
/*
* The 'sync' flag can have the the following values
*/
/*
* DMA 'mode' flags:
*/
#define COLDF_DMA_MODE_CC_TO (1<<0)
/* invalidate cache covering 'to' area */
#define COLDF_DMA_MODE_CC_FROM (1<<1)
/* invalidate cache covering 'from' area */
#define COLDF_DMA_MODE_CC_MSK (3<<0)
/* use external (HW) signal to start DMA; */
#define COLDF_DMA_MODE_START_EXT (MCF5282_DMA_DCR_EEXT)
/* start DMA immediately by software */
#define COLDF_DMA_MODE_START_INT (MCF5282_DMA_DCR_START)
/* enable interrupt on completion or error (user still
* must hook an ISR).
*/
#define COLDF_DMA_MODE_SYNC_IRQ (MCF5282_DMA_DCR_INT)
/* poll for DMA completion (mostly useful for timing/debugging) */
#define COLDF_DMA_MODE_SYNC_POLL (1<<2)
/* transfer from peripheral to memory (used to optimize port width etc)
*/
#define COLDF_DMA_MODE_TOMEM (1<<3)
#define COLDF_DMA_MODE_TO_MEM (0 \
/* | MCF5282_DMA_DCR_INT */ \
/* | MCF5282_DMA_DCR_EEXT */ \
/* | MCF5282_DMA_DCR_CS */ \
| MCF5282_DMA_DCR_AA \
| MCF5282_DMA_DCR_BWC_DMA \
/* | MCF5282_DMA_DCR_BWC_512 */ \
/* | MCF5282_DMA_DCR_BWC_1024 */ \
/* | MCF5282_DMA_DCR_BWC_2048 */ \
/* | MCF5282_DMA_DCR_BWC_4096 */ \
/* | MCF5282_DMA_DCR_BWC_8192 */ \
/* | MCF5282_DMA_DCR_BWC_16384 */ \
/* | MCF5282_DMA_DCR_BWC_32768 */ \
/* | MCF5282_DMA_DCR_SINC */ \
/* | MCF5282_DMA_DCR_SSIZE_LONG */ \
/* | MCF5282_DMA_DCR_SSIZE_BYTE */ \
| MCF5282_DMA_DCR_SSIZE_WORD \
/* | MCF5282_DMA_DCR_SSIZE_LINE */ \
| MCF5282_DMA_DCR_DINC \
/* line is apparently slowest, LONG is best */ \
/* | MCF5282_DMA_DCR_DSIZE_LINE */ \
| MCF5282_DMA_DCR_DSIZE_LONG \
/* | MCF5282_DMA_DCR_DSIZE_BYTE */ \
/* | MCF5282_DMA_DCR_DSIZE_WORD */ \
/* | MCF5282_DMA_DCR_START */ \
| MCF5282_DMA_DCR_AT)
#define COLDF_DMA_MODE_FROM_MEM (0 \
/* | MCF5282_DMA_DCR_INT */ \
/* | MCF5282_DMA_DCR_EEXT */ \
/* | MCF5282_DMA_DCR_CS */ \
| MCF5282_DMA_DCR_AA \
| MCF5282_DMA_DCR_BWC_DMA \
/* | MCF5282_DMA_DCR_BWC_512 */ \
/* | MCF5282_DMA_DCR_BWC_1024 */ \
/* | MCF5282_DMA_DCR_BWC_2048 */ \
/* | MCF5282_DMA_DCR_BWC_4096 */ \
/* | MCF5282_DMA_DCR_BWC_8192 */ \
/* | MCF5282_DMA_DCR_BWC_16384 */ \
/* | MCF5282_DMA_DCR_BWC_32768 */ \
| MCF5282_DMA_DCR_SINC \
/* | MCF5282_DMA_DCR_SSIZE_LONG */ \
/* | MCF5282_DMA_DCR_SSIZE_BYTE */ \
/* | MCF5282_DMA_DCR_SSIZE_WORD */ \
| MCF5282_DMA_DCR_SSIZE_LINE \
/* | MCF5282_DMA_DCR_DINC */ \
/* | MCF5282_DMA_DCR_DSIZE_LINE */ \
| MCF5282_DMA_DCR_DSIZE_LONG \
/* | MCF5282_DMA_DCR_DSIZE_BYTE */ \
/* | MCF5282_DMA_DCR_DSIZE_WORD */ \
/* | MCF5282_DMA_DCR_START */ \
| MCF5282_DMA_DCR_AT)
/* Increment source/destination pointer;
* NOTE: if TOMEM is set then DINC is automatically set;
* if TOMEM is clear then SINC is automatically set.
* This flag only affects SINC (TOMEM set) or DINC (TOMEM clear),
* respectively.
*/
#define COLDF_DMA_MODE_SINC (MCF5282_DMA_DCR_SINC)
#define COLDF_DMA_MODE_DINC (MCF5282_DMA_DCR_DINC)
/* strip all non-DCR flags -- INTERNAL USE ONLY */
#define COLDF_DMA_MODE_MASK (~0xf)
/*
* mode can be a combination of flags above but it can
* also just be any combination of DMA/DCR flags.
*/
/*
* compute pre-cooked mode word from simple parameters
*
* 'ext' nonzero: use external/HW start condition, (SW start otherwise)
* 'poll' nonzero: poll for completion (poll>0) or enable irq (poll<0)
* 'tomem' > 0: use combination of flags useful for xfer from
* periph. port to memory.
* 'tomem' <= 0: use combination of flags useful for xfer from
* memory to periph. port.
* 'tomem' > 1: as tomem==1 but DO increment source address.
* 'tomem' < 0: as tomem==0 but DO increment dest address.
*
* NOTE: 'tomem == 1' does NOT increment the source address;
* 'tomem == 0' does NOT increment the dest address.
*
* 'cache_coherency'
* 0: do not flush source nor invalidate destination from
* cache.
* >0: IF (tomem>0) invalidate destination ELSE flush source
* <0: flush source and invalidate destination from cache.
*/
uint32_t
coldfDMAMode(int ext, int poll, int tomem, int cache_coherency);
int
coldfDMAStart(int chan, uint8_t *to, uint8_t *from, uint32_t size, uint32_t mode);
/*
* Obtain interrupt vector for DMA channel 'chan';
* -1 is returned if the channel number is out
* of range
*/
int
coldfDMAIrqVector(int chan);
/*
* Read status and reset 'DONE' if set.
* Returns nonzero of an error had occurred
* during the last DMA transfer.
*/
int
coldfDMAAck(int chan);
/* Dump raw registers of DMA channel (0..3) and DMA timer (0..3) to stdout
* RETURNS: 0 on success, -1 (invalid argument)
*/
int
coldfDMADump(int chan, int timer);
/* ==== CHIP SELECT CONFIGURATION ==== */
#define CSELECT_FLAG_OFF ((uint32_t)-1) /* disable this CS */
#define CSELECT_FLAG_BWEN (1<<3) /* enable burst writes */
#define CSELECT_FLAG_BREN (1<<4) /* enable burst reads */
#define CSELECT_FLAG_WP (1<<0) /* write protection */
#define CSELECT_FLAG_AA (1<<8) /* internal cycle termination */
#define CSELECT_FLAG_WS(n) (((n)&0xf)<<10) /* wait states */
int
coldfCsSetup(int cs, uint32_t flags);
/* ============= FEC PHY ============= */
/* Read/Write the FEC's MII registers */
int
getMII(int phyNumber, int regNumber);
/*
* Write MII register
* Busy-waits, but transfer time should be short!
*/
void
setMII(int phyNumber, int regNumber, int value);
/* ============== QSPI =============== */
/* NOTE: All access to the hardware is protected by an internal
* mutex. Hence, it is safe for multiple threads sharing a
* common setup to use the driver 'concurrently'. The mutex
* serializes 'Write' and 'WriteRead' calls.
*
* Note that 'Write' doesn't wait for the SPI transaction
* to finish while 'WriteRead' does.
*
* After a 'Write' operation, the driver keeps the mutex
* until completion so that a second 'Write' blocks until
* the first one has completed.
*/
/* Initialize the driver */
int
coldfQspiInit();
/* Setup the QSPI interface
*
* 'sysclock': system clock in Hz (e.g., 64000000)
* NOTE: if 0 is passed then the routine will try to
* determine the clock speed automatically (returns nonzero
* if that fails).
*
* 'baudrate': QSPI clock rate in Hz
*
* setup_ns: delay from CS activation to active clock edge (in ns)
* NOTE: value of zero selects default of 1/2 QSPI clock period
*
* hold_ns: delay after CS deactivation until next transfer (in ns)
* NOTE: value of zero selects default of 17/sysclock
* which is the lowest possible value.
*
* flags: ORed options:
* CLK_ACTVLOW: active clock level is the low level.
* CLK_FALLING: data is latched on the active->inactive transition of
* the clock and changed on the inactive->active transition.
* CS_ACTVLOW: CS is driven high between transfers.
*/
/* Clock active low */
#define DRV5282_QSPI_SETUP_CLK_ACTVLOW 1
/* Data latched on falling edge (i.e., clock active->inactive transition) */
#define DRV5282_QSPI_SETUP_CLK_FALLING 2
#define DRV5282_QSPI_SETUP_CS_ACTVLOW 4
int
coldfQspiSetup(
uint32_t sysclock,
uint32_t baudrate,
uint32_t setup_ns,
uint32_t hold_ns,
uint32_t flags);
/* Write 'n' bytes to TX RAM and issue command. This also
* clocks data into the RX RAM (which is retrieved by separate
* command).
*
* All bytes go the same (set) of devices (chip-selects).
*
* 'cs_mask' reflects the values driven on the CS lines
* during the transaction. The 'inactive' state is programmed
* by the 'Setup' routine.
*
* RETURNS: # bytes written or <0 on error
*
* NOTE: The driver mutex is eventually released by the ISR
* when the transaction is complete but the 'Write'
* routine does not wait for that to happen.
* You can explicitely synchronize either by calling
* the 'Status' routine (which waits until it gets
* the mutex) or by using the 'WriteRead' entry point.
*/
int
coldfQspiWrite(uint8_t *buf, int n, uint16_t cs_mask);
/* Read and clear status
*
* RETURNS:
* 0 after successful transfer
* QIR status flags on transfer error
* -1 if status was clear (xfer completed flag not set)
*/
int
coldfQspiStatus();
/* Read n bytes from 'offset' out of RX RAM.
* This routine does not perform any actual
* transfer on the SPI but just reads data
* (non-destructively) from the RX buffer.
*
* RETURNS: # bytes read or <0 on error:
*/
int
coldfQspiRead(uint8_t *buf, unsigned offset, int n);
/* Write a buffer (see coldfQspiWrite), wait for the transfer
* to complete and read received data (see coldfQspiRead).
* All actions are performed 'atomically' (protected by the driver mutex).
*
* NOTES: 'rbuf' may be equal to 'tbuf' or it may be NULL (in which case
* received data is thrown away - this is effectively a synchronous
* write operation).
* 'tbuf' may also be NULL which makes this effectively a synchronous
* read operation.
*
* RETURNS: # of bytes transferred or < 0 on error
*
* -1: parameter error
* -QspiStatus return value: transmission error or abort
*/
int
coldfQspiWriteRead(uint8_t *tbuf, uint8_t *rbuf, int n, uint16_t cs_mask);
/* Shut down the driver */
int
coldfQspiCleanup();
/* Copy contents of a file to flash.
*
* 'path' Path of a file.
* 'bank' is unused (compatibility with other BSPs).
* 'offset' should be 0 for a boot image.
*
* RETURNS: 0 on success, nonzero on error.
*/
int
BSP_flashWriteFile(int bank, uint32_t offset, char *path);
/* alternate entry point:
* 'quiet': 0 all messages printed, ask for confirmation
* before erasing.
* 'quiet': 1 all messages printed, no questions asked
* 'quiet': 2 only error messages printed, no questions asked
* 'quiet': 3 no messages printed, no questions asked
*/
int
BSP_flashWriteFile_1(int bank, uint32_t offset, char *path, int quiet);
#ifdef __cplusplus
}
#endif
#endif