]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/spi_tms570.c
Add SPI devices available on hydctr board
[pes-rpp/rpp-lib.git] / rpp / src / drv / spi_tms570.c
1 /* Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
2  *
3  * This document contains proprietary information belonging to Czech
4  * Technical University in Prague. Passing on and copying of this
5  * document, and communication of its contents is not permitted
6  * without prior written authorization.
7  *
8  * File : spi_tms570.c
9  *
10  * Code based on Halcogen generated source code
11  */
12
13 #include "drv/spi.h"
14 #include "sys/port.h"
15 #include "sys/ti_drv_dmm.h"
16 #include "drv/spi_def.h"
17 #include "drv/spi_tms570.h"
18
19 #define SPI_FLG_TXINT_m     (1 << 9)
20 #define SPI_FLG_RXINT_m     (1 << 8)
21
22 #define SPI_INT0_TXINTENA_m (1 << 9)
23 #define SPI_INT0_RXINTENA_m (1 << 8)
24
25 #define SPI_DAT1_CSHOLD_m   (1 << 28)
26
27 typedef volatile struct spiBase {
28         uint32_t GCR0;          /**< 0x0000: Global Control 0 */
29 #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
30         uint32_t GCR1 : 8U;       /**< 0x0007: Global Control 1 */
31         uint32_t PD : 1U;         /**< 0x0006: Power down bit */
32         uint32_t : 7U;
33         uint32_t LB : 1U;         /**< 0x0005: Loop back bit */
34         uint32_t : 7U;
35         uint32_t ENA : 1U;        /**< 0x0004: SPI Enable bit */
36         uint32_t : 7U;
37         uint32_t INT0 : 16U;      /**< 0x000A: Interrupt Enable bits */
38         uint32_t DMAREQEN : 1U;       /**< 0x0009: DMA Request enable */
39         uint32_t : 7U;
40         uint32_t ENAHIGHZ : 1U;       /**< 0x0008: Enable HIGHZ outputs */
41         uint32_t : 7U;
42 #else
43         uint32_t : 7U;
44         uint32_t ENA : 1U;        /**< 0x0004: SPI Enable bit */
45         uint32_t : 7U;
46         uint32_t LB : 1U;         /**< 0x0005: Loop back bit */
47         uint32_t : 7U;
48         uint32_t PD : 1U;         /**< 0x0006: Power down bit */
49         uint32_t GCR1 : 8U;       /**< 0x0007: Global Control 1 */
50         uint32_t : 7U;
51         uint32_t ENAHIGHZ : 1U;       /**< 0x0008: Enable HIGHZ outputs */
52         uint32_t : 7U;
53         uint32_t DMAREQEN : 1U;       /**< 0x0009: DMA Request enable */
54         uint32_t INT0 : 16U;      /**< 0x000A: Interrupt Enable bits */
55 #endif
56         uint32_t LVL;           /**< 0x000C: Interrupt Level */
57 #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
58         uint32_t FLG : 16U;       /**< 0x0012: Interrupt flags */
59         uint32_t : 8U;
60         uint32_t BUFINIT : 1U;        /**< 0x0010: Buffer initialization active flag */
61         uint32_t : 7U;
62 #else
63         uint32_t : 7U;
64         uint32_t BUFINIT : 1U;        /**< 0x0010: Buffer initialization active flag */
65         uint32_t : 8U;
66         uint32_t FLG : 16U;       /**< 0x0012: Interrupt flags */
67 #endif
68         uint32_t PCFUN;         /**< 0x0014: Function Pin Enable */
69         uint32_t PCDIR;         /**< 0x0018: Pin Direction */
70         uint32_t PCDIN;         /**< 0x001C: Pin Input Latch */
71         uint32_t PCDOUT;        /**< 0x0020: Pin Output Latch */
72         uint32_t PCSET;         /**< 0x0024: Output Pin Set */
73         uint32_t PCCLR;         /**< 0x0028: Output Pin Clr */
74         uint32_t PCPDR;         /**< 0x002C: Open Drain Output Enable */
75         uint32_t PCDIS;         /**< 0x0030: Pullup/Pulldown Disable */
76         uint32_t PCPSL;         /**< 0x0034: Pullup/Pulldown Selection */
77         uint32_t DAT0;          /**< 0x0038: Transmit Data */
78         uint32_t DAT1;          /**< 0x003C: Transmit Data with Format and Chip Select */
79         uint32_t BUF;           /**< 0x0040: Receive Buffer */
80         uint32_t EMU;           /**< 0x0044: Emulation Receive Buffer */
81         uint32_t DELAY;         /**< 0x0048: Delays */
82         uint32_t CSDEF;         /**< 0x004C: Default Chip Select */
83         uint32_t FMT0;          /**< 0x0050: Data Format 0 */
84         uint32_t FMT1;          /**< 0x0054: Data Format 1 */
85         uint32_t FMT2;          /**< 0x0058: Data Format 2 */
86         uint32_t FMT3;          /**< 0x005C: Data Format 3 */
87         uint32_t INTVECT0;      /**< 0x0060: Interrupt Vector 0 */
88         uint32_t INTVECT1;      /**< 0x0064: Interrupt Vector 1 */
89         uint32_t SRSEL;         /**< 0x0068: Slew Rate Select */
90
91         uint32_t PMCTRL;        /**< 0x006C: Parallel Mode Control */
92 #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
93         uint32_t MIBSPIE : 16U;       /**< 0x0072: MibSPI Enable */
94         uint32_t RAMACCESS : 16U;     /**< 0x0070: RX Ram Write Access Enable */
95 #else
96         uint32_t RAMACCESS : 16U;     /**< 0x0070: RX Ram Write Access Enable */
97         uint32_t MIBSPIE : 16U;       /**< 0x0072: MibSPI Enable */
98 #endif
99
100         uint32_t RESERVED[48U];     /**< 0x006C to 0x0130: Reserved */
101         uint32_t IOLPKTSTCR;        /**< 0x0134: IO loopback */
102 } spiBASE_compat_t;
103
104 #define spi_compat_REG2     ((spiBASE_compat_t *)0xFFF7F600U)
105 #define spi_compat_REG4     ((spiBASE_compat_t *)0xFFF7FA00U)
106 #define mibspi_compat_REG1  ((spiBASE_compat_t *)0xFFF7F400U)
107 #define mibspi_compat_REG3  ((spiBASE_compat_t *)0xFFF7F800U)
108 #define mibspi_compat_REG5  ((spiBASE_compat_t *)0xFFF7FC00U)  /* NOT USED ON RPP BOARD */
109
110 /* SPI interface */
111 struct spi_tms570_iface {
112         spi_drv_t spi_drv;
113         spiBASE_compat_t *reg;      /* Base Reg. for SPI device register array */
114         unsigned txcnt; /* No. of transfered bytes for msg_act */
115         unsigned rxcnt; /* No. of received bytes for msg_act */
116         spi_dev_t *spi_devs;    /* Pointer to table holding information about SPI devices bound to the interface */
117         uint32_t transfer_ctrl; /* Transfer configuration -- upper 16 bits of SPIDAT1 register */
118         /* TODO: Add FMT description here if we need different formats */
119 };
120
121 spi_tms570_iface_t spi_iface[5] = {
122         [SPI_IFACE1] = { .reg = mibspi_compat_REG1,     },
123         [SPI_IFACE2] = { .reg = spi_compat_REG2,        },
124         [SPI_IFACE3] = { .reg = mibspi_compat_REG3,     },
125         [SPI_IFACE4] = { .reg = spi_compat_REG4,        },
126         [SPI_IFACE5] = { .reg = mibspi_compat_REG5,     },
127 };
128
129 spi_drv_t *spi_tms570_get_iface(enum spi_device dev)
130 {
131         return &spi_iface[spi_devs[dev].iface].spi_drv;
132 }
133
134 static int spi_tms570_ctrl_fnc(spi_drv_t *ifc, int ctrl, void *p);
135
136 /*
137    Universal piece of code initializing SPI or MibSPI
138    devices in "compatibility" mode.
139    8 CS pins are initialized on each device -- even if
140    it does not have so much of them.
141    ENA register is set even on SPI devices which do not have it --
142    this should not be an issue
143  */
144 static void spiInit(spiBASE_compat_t *spiREG)
145 {
146         /** bring SPI out of reset */
147         spiREG->GCR0 = 1U;
148
149         /** SPI master mode and clock configuration */
150         spiREG->GCR1 = (1 << 1) /* CLOKMOD */
151                                    |1; /* MASTER */
152
153         /** SPI enable pin configuration */
154         spiREG->ENAHIGHZ = 0;   /* ENABLE HIGHZ */
155
156         /** - Delays */
157         spiREG->DELAY = (0 << 24)   /* C2TDELAY */
158                                         | (0 << 16) /* T2CDELAY */
159                                         | (0 << 8) /* T2EDELAY */
160                                         | 0; /* C2EDELAY */
161
162         /** - Data Format 0 */
163         /* TODO: Set the formats from spi_tms570_iface_t if we need different formats */
164         spiREG->FMT0 = (0 << 24)    /* wdelay */
165                                    | (0 << 23) /* parity Polarity */
166                                    | (0 << 22) /* parity enable */
167                                    | (0 << 21) /* wait on enable */
168                                    | (0 << 20) /* shift direction */
169                                    | (0 << 17) /* clock polarity */
170                                    | (0 << 16) /* clock phase */
171                                    | ((RPP_VCLK1_FREQ / SPI_BR_FORMAT0 - 1 ) << 8) /* baudrate prescale */
172                                    | 8; /* data word length */
173
174         /** - Data Format 1 */
175         spiREG->FMT1 = (0 << 24)    /* wdelay */
176                                    | (0 << 23) /* parity Polarity */
177                                    | (0 << 22) /* parity enable */
178                                    | (0 << 21) /* wait on enable */
179                                    | (0 << 20) /* shift direction */
180                                    | (0 << 17) /* clock polarity */
181                                    | (1 << 16) /* clock phase */
182                                    | ((RPP_VCLK1_FREQ / SPI_BR_FORMAT1 - 1 ) << 8) /* baudrate prescale */
183                                    | 8; /* data word length */
184
185         /** - Data Format 2 */
186         spiREG->FMT2 = (0 << 24)    /* wdelay */
187                                    | (0 << 23) /* parity Polarity */
188                                    | (0 << 22) /* parity enable */
189                                    | (0 << 21) /* wait on enable */
190                                    | (0 << 20) /* shift direction */
191                                    | (0 << 17) /* clock polarity */
192                                    | (0 << 16) /* clock phase */
193                                    | ((RPP_VCLK1_FREQ / SPI_BR_FORMAT2 - 1 ) << 8) /* baudrate prescale */
194                                    | 8; /* data word length */
195
196         /** - Data Format 3 */
197         spiREG->FMT3 = (0 << 24)    /* wdelay */
198                                    | (0 << 23) /* parity Polarity */
199                                    | (0 << 22) /* parity enable */
200                                    | (0 << 21) /* wait on enable */
201                                    | (0 << 20) /* shift direction */
202                                    | (0 << 17) /* clock polarity */
203                                    | (0 << 16) /* clock phase */
204                                    | ((RPP_VCLK1_FREQ / SPI_BR_FORMAT3 - 1 ) << 8) /* baudrate prescale */
205                                    | 8; /* data word length */
206
207         /** - set interrupt levels */
208         spiREG->LVL = (0 << 9)  /* TXINT */
209                                   | (0 << 8) /* RXINT */
210                                   | (0 << 6) /* OVRNINT */
211                                   | (0 << 4) /* BITERR */
212                                   | (0 << 3) /* DESYNC */
213                                   | (0 << 2) /* PARERR */
214                                   | (0 << 1) /* TIMEOUT */
215                                   | (0); /* DLENERR */
216
217         /** - clear any pending interrupts */
218         spiREG->FLG = 0xFFFFU;
219
220         /** - enable interrupts */
221         spiREG->INT0 = (0 << 9) /* TXINT */
222                                    | (0 << 8) /* RXINT */
223                                    | (0 << 6) /* OVRNINT */
224                                    | (0 << 4) /* BITERR */
225                                    | (0 << 3) /* DESYNC */
226                                    | (0 << 2) /* PARERR */
227                                    | (0 << 1) /* TIMEOUT */
228                                    | (0); /* DLENERR */
229
230         /** initialize SPI Port */
231
232         /** - SPI Port output values */
233         spiREG->PCDOUT = 1  /* SCS[0] */
234                                          | (1 << 1) /* SCS[1] */
235                                          | (1 << 2) /* SCS[2] */
236                                          | (1 << 3) /* SCS[3] */
237                                          | (1 << 4) /* SCS[4] */
238                                          | (1 << 5) /* SCS[5] */
239                                          | (1 << 6) /* SCS[6] */
240                                          | (1 << 7) /* SCS[7] */
241                                          | (0 << 8) /* ENA */
242                                          | (0 << 9) /* CLK */
243                                          | (0 << 10) /* SIMO */
244                                          | (0 << 11); /* SOMI */
245
246         /** - SPI Port direction */
247         spiREG->PCDIR = 1   /* SCS[0] */
248                                         | (1 << 1) /* SCS[1] */
249                                         | (1 << 2) /* SCS[2] */
250                                         | (1 << 3) /* SCS[3] */
251                                         | (1 << 4) /* SCS[4] */
252                                         | (1 << 5) /* SCS[5] */
253                                         | (1 << 6) /* SCS[6] */
254                                         | (1 << 7) /* SCS[7] */
255                                         | (0 << 8) /* ENA */
256                                         | (1 << 9) /* CLK */
257                                         | (1 << 10) /* SIMO */
258                                         | (0 << 11); /* SOMI */
259
260         /** - SPI Port open drain enable */
261         spiREG->PCPDR = 0   /* SCS[0] */
262                                         | (0 << 1) /* SCS[1] */
263                                         | (0 << 2) /* SCS[2] */
264                                         | (0 << 3) /* SCS[3] */
265                                         | (0 << 4) /* SCS[4] */
266                                         | (0 << 5) /* SCS[5] */
267                                         | (0 << 6) /* SCS[6] */
268                                         | (0 << 7) /* SCS[7] */
269                                         | (0 << 8) /* ENA */
270                                         | (0 << 9) /* CLK */
271                                         | (0 << 10) /* SIMO */
272                                         | (0 << 11); /* SOMI */
273
274         /** - SPI Port pullup / pulldown selection */
275         spiREG->PCPSL = 1   /* SCS[0] */
276                                         | (1 << 1) /* SCS[1] */
277                                         | (1 << 2) /* SCS[2] */
278                                         | (1 << 3) /* SCS[3] */
279                                         | (1 << 4) /* SCS[4] */
280                                         | (1 << 5) /* SCS[5] */
281                                         | (1 << 6) /* SCS[6] */
282                                         | (1 << 7) /* SCS[7] */
283                                         | (1 << 8) /* ENA */
284                                         | (1 << 9) /* CLK */
285                                         | (1 << 10) /* SIMO */
286                                         | (1 << 11); /* SOMI */
287
288         /** - SPI Port pullup / pulldown enable*/
289         spiREG->PCDIS = 0   /* SCS[0] */
290                                         | (0 << 1) /* SCS[1] */
291                                         | (0 << 2) /* SCS[2] */
292                                         | (0 << 3) /* SCS[3] */
293                                         | (0 << 4) /* SCS[4] */
294                                         | (0 << 5) /* SCS[5] */
295                                         | (0 << 6) /* SCS[6] */
296                                         | (0 << 7) /* SCS[7] */
297                                         | (0 << 8) /* ENA */
298                                         | (0 << 9) /* CLK */
299                                         | (0 << 10) /* SIMO */
300                                         | (0 << 11); /* SOMI */
301
302         /* SPI set all pins to functional */
303         spiREG->PCFUN = 1   /* SCS[0] */
304                                         | (1 << 1) /* SCS[1] */
305                                         | (1 << 2) /* SCS[2] */
306                                         | (1 << 3) /* SCS[3] */
307                                         | (1 << 4) /* SCS[4] */
308                                         | (1 << 5) /* SCS[5] */
309                                         | (1 << 6) /* SCS[6] */
310                                         | (1 << 7) /* SCS[7] */
311                                         | (1 << 8) /* ENA */
312                                         | (1 << 9) /* CLK */
313                                         | (1 << 10) /* SIMO */
314                                         | (1 << 11); /* SOMI */
315
316         /* Default CS logic levels */
317         spiREG->CSDEF = 0xFF;
318
319         /** Set MibSPI devices into compatibility mode --
320             "SPI" devices will hopefully ignore this */
321         spiREG->MIBSPIE = 0U;
322
323         /** - Finally start SPI */
324         spiREG->ENA = 1U;
325 }
326
327 static void init_iface(spi_tms570_iface_t *iface)
328 {
329         spiInit(iface->reg);
330         iface->spi_drv.ctrl_fnc = spi_tms570_ctrl_fnc;
331         spi_rq_queue_init_head(&(iface->spi_drv));
332         iface->spi_drv.msg_act = NULL;
333         iface->spi_drv.flags = 0;
334 }
335
336 void spi_tms570_init()
337 {
338         int i;
339
340         for (i = 0; i < ARRAY_SIZE(spi_iface); i++)
341                 init_iface(&spi_iface[i]);
342
343         //dmmREG->PC5 = (1 << DMM_DATA5); /* Set to L */
344         //dmmREG->PC5 = (1 << DMM_DATA6); /* Set to L */
345 }
346
347
348 static int spi_tms570_ctrl_fnc(spi_drv_t *ifc, int ctrl, void *p)
349 {
350         spi_tms570_iface_t *tms570_drv =
351                 UL_CONTAINEROF(ifc, spi_tms570_iface_t, spi_drv);
352
353         switch (ctrl) {
354         case SPI_CTRL_WAKE_RQ:
355                 if (spi_rq_queue_is_empty(ifc))
356                         return 0;
357
358                 tms570_drv->reg->INT0 = SPI_INT0_TXINTENA_m;
359                 // Enable TXINT (Causes an interrupt
360                 // to be generated every time data is written to the shift
361                 // register, so that the next word can be written to TXBUF.
362                 // (=transmitter empty interrupt)
363                 // Setting this bit will generate an interrupt if the
364                 // TXINTFLG bit (SPI Flag Register (SPIFLG)[9]) is set to 1.;
365                 // An interrupt request will be generated as soon as this
366                 // bit is set to 1.
367                 return 0;
368
369         default:
370                 return -1;
371         }
372 }
373
374
375
376 /* -------------------------------------------------------------------------- */
377
378
379
380 void spi_tms570_isr(int spi_ifc, uint32_t flags)
381 {
382         spi_msg_t *msg;
383         spi_tms570_iface_t *iface = &spi_iface[spi_ifc];
384         const spi_dev_t *dev;
385         spi_isr_lock_level_t saveif;
386         uint8_t val_to_wr;
387         uint32_t cs;
388         unsigned int rxcnt;
389         unsigned int txcnt;
390         unsigned int rq_len;
391         unsigned int rx_data;
392         int stop_fl;
393
394         if (flags & SPI_FLG_TXINT_m) {
395                 do {
396                         msg = iface->spi_drv.msg_act;
397                         if (!msg) { /* Is there any MSG being processed? */
398                                 /* If not, get one from a queue */
399                                 spi_isr_lock(saveif);
400                                 msg = iface->spi_drv.msg_act =
401                                                   spi_rq_queue_first(&iface->spi_drv);
402                                 spi_isr_unlock(saveif);
403
404                                 if (!msg) { /* Nothing to process */
405                                         volatile unsigned int dummy_read;
406                                         /* Disable TXEMPTY IRQ */
407                                         iface->reg->INT0 = 0x00;
408                                         iface->reg->FLG = 0x00;
409                                         dummy_read = iface->reg->BUF;
410                                         // FIXME "INT |= " with disabled IRQ ??
411                                         return;
412                                 }
413
414                                 iface->txcnt = 0;
415                                 iface->rxcnt = 0;
416                                 dev = &spi_devs[msg->dev];
417                                 cs = dev->cs;
418                                 iface->transfer_ctrl =
419                                         (cs & 0xff) << 16
420                                         | (dev->wdel & 0x1) << 26
421                                         | (dev->cshold & 0x1) << 28
422                                         | (dev->dfsel & 0x3) << 24;
423
424 #if defined(TARGET_TMS570_RPP)
425                                 /* GPIO CS -- setting the multiplexer */
426                                 if (cs > 0xff) {
427                                         switch (cs & 0xFF00) {
428                                         case SPI_CS_DMM0:
429                                                 dmmREG->PC5 = (1 << DMM_DATA5); /* Set to L */
430                                                 dmmREG->PC5 = (1 << DMM_DATA6); /* Set to L */
431                                                 break;
432                                         case SPI_CS_DMM1:
433                                                 dmmREG->PC4 = (1 << DMM_DATA5); /* Set to H */
434                                                 dmmREG->PC5 = (1 << DMM_DATA6); /* Set to L */
435                                                 break;
436                                         case SPI_CS_DMM2:
437                                                 dmmREG->PC5 = (1 << DMM_DATA5); /* Set to L */
438                                                 dmmREG->PC4 = (1 << DMM_DATA6); /* Set to H */
439                                                 break;
440                                         }
441                                 }
442 #endif
443                         }
444
445                         rq_len = msg->rq_len;
446                         rxcnt = iface->rxcnt;
447                         txcnt = iface->txcnt;
448                         /* RX/TX transfers */
449                         do {
450                                 /* Receive all the incoming data */
451                                 while (iface->reg->FLG & SPI_FLG_RXINT_m) {
452                                         rx_data = iface->reg->BUF;
453
454                                         if (msg->rx_buf && (rxcnt < rq_len)) {
455                                                 /* This relies on all FMTs having 8 bit CHARLEN */
456                                                 msg->rx_buf[rxcnt++] = rx_data & 0xFF;
457                                         } else
458                                                 rxcnt++;
459                                 }
460
461                                 /* Send some data */
462                                 while (1) {
463                                         /* Tx buffer full or nothing to send */
464                                         stop_fl = ((txcnt >= rq_len) ||
465                                                            (!(iface->reg->FLG & SPI_FLG_TXINT_m)));
466
467                                         if (stop_fl)
468                                                 break;
469                                         /* Make it possible to write "empty data"
470                                            for "read transfers" */
471                                         if (msg->tx_buf) {
472                                                 /* This relies on all FMTs having 8 bit CHARLEN */
473                                                 val_to_wr = msg->tx_buf[txcnt++];
474                                         } else {
475                                                 val_to_wr = 0x00;
476                                                 txcnt++;
477                                         }
478
479                                         if (txcnt == rq_len) /* Disable CS after last byte of the transfer */
480                                                 iface->transfer_ctrl &= ~SPI_DAT1_CSHOLD_m;
481
482                                         iface->reg->DAT1 =
483                                                 (uint32_t)(iface->transfer_ctrl | val_to_wr);
484
485                                         /* We just received something */
486                                         if (iface->reg->FLG & SPI_FLG_RXINT_m)
487                                                 break;
488                                 }
489                         } while (!stop_fl);
490                         iface->rxcnt = rxcnt;
491                         iface->txcnt = txcnt;
492
493                         if ((rxcnt >= rq_len) ||
494                                 (!msg->rx_buf && (txcnt >= rq_len) &&
495                                  !(iface->reg->FLG & SPI_FLG_RXINT_m))) { // FIXME
496
497                                 /* Sending of the message successfully finished */
498                                 spi_isr_lock(saveif);
499                                 spi_rq_queue_del_item(msg);
500                                 msg->flags |= SPI_MSG_FINISHED;
501                                 iface->spi_drv.msg_act = NULL;
502                                 spi_isr_unlock(saveif);
503                                 if (msg->callback)
504                                         msg->callback(&iface->spi_drv,
505                                                                   SPI_MSG_FINISHED, msg);
506
507                                 continue;
508                         }
509                         if (txcnt < rq_len)
510                                 iface->reg->INT0 = SPI_INT0_TXINTENA_m;
511                         else
512                                 iface->reg->INT0 = SPI_INT0_RXINTENA_m;
513
514                 } while (1);
515         }
516 }
517
518 #pragma INTERRUPT(spi2LowLevelInterrupt, IRQ)
519 void spi2LowLevelInterrupt(void)
520 {
521         uint32_t flags = spi_compat_REG2->FLG; // & (~spiREG2->LVL & 0x035F);
522
523         spi_tms570_isr(2 - 1, flags);
524 }
525
526 #pragma INTERRUPT(spi2HighLevelInterrupt, IRQ)
527 void spi2HighLevelInterrupt(void)
528 {
529         uint32_t flags = spi_compat_REG2->FLG; // & (~spiREG2->LVL & 0x035F);
530
531         spi_tms570_isr(2 - 1, flags);
532 }
533
534 #pragma INTERRUPT(spi4LowLevelInterrupt, IRQ)
535 void spi4LowLevelInterrupt(void)
536 {
537         uint32_t flags = spi_compat_REG4->FLG; // & (~spiREG4->LVL & 0x035F);
538
539         spi_tms570_isr(4 - 1, flags);
540 }
541
542 #pragma INTERRUPT(spi4HighLevelInterrupt, IRQ)
543 void spi4HighLevelInterrupt(void)
544 {
545         uint32_t flags = spi_compat_REG4->FLG; // & (~spiREG4->LVL & 0x035F);
546
547         spi_tms570_isr(4 - 1, flags);
548 }
549
550 #pragma INTERRUPT(mibspi1HighLevelInterrupt, IRQ)
551 void mibspi1HighLevelInterrupt(void)
552 {
553         uint32_t flags = mibspi_compat_REG1->FLG; // & (~mibspiREG1->LVL & 0x035F);
554
555         spi_tms570_isr(1 - 1, flags);
556 }
557
558 #pragma INTERRUPT(mibspi1LowLevelInterrupt, IRQ)
559 void mibspi1LowLevelInterrupt(void)
560 {
561         uint32_t flags = mibspi_compat_REG1->FLG; // & (~mibspiREG1->LVL & 0x035F);
562
563         spi_tms570_isr(1 - 1, flags);
564 }
565
566 #pragma INTERRUPT(mibspi3HighInterruptLevel, IRQ)
567 void mibspi3HighInterruptLevel(void)
568 {
569         uint32_t flags = mibspi_compat_REG3->FLG; // & (~mibspiREG3->LVL & 0x035F);
570
571         spi_tms570_isr(3 - 1, flags);
572 }
573
574 #pragma INTERRUPT(mibspi3LowLevelInterrupt, IRQ)
575 void mibspi3LowLevelInterrupt(void)
576 {
577         uint32_t flags = mibspi_compat_REG3->FLG; // & (~mibspiREG3->LVL & 0x035F);
578
579         spi_tms570_isr(3 - 1, flags);
580 }