2 * @brief MIBSPI Driver Implementation File
8 /* (c) Texas Instruments 2009-2012, All rights reserved. */
10 /* USER CODE BEGIN (0) */
13 #include "sys/ti_drv_mibspi.h"
15 /* USER CODE BEGIN (1) */
18 /** @fn void mibspiInit(void)
19 * @brief Initializes the MIBSPI Driver
21 * This function initializes the MIBSPI module.
27 /* USER CODE BEGIN (2) */
33 /** @b intalise @b MIBSPI5 */
35 /** bring MIBSPI out of reset */
36 mibspiREG5->GCR0 = 1U;
38 /** enable MIBSPI RAM Parity */
39 mibspiREG5->EDEN = 0x00000005U;
41 /** enable MIBSPI5 multibuffered mode and enable buffer RAM */
42 mibspiREG5->MIBSPIE = 1U;
44 /** MIBSPI5 master mode and clock configuration */
45 mibspiREG5->GCR1 = (1 << 1) /* CLOKMOD */
48 /** MIBSPI5 enable pin configuration */
49 mibspiREG5->ENAHIGHZ = 0; /* ENABLE HIGHZ */
52 mibspiREG5->DELAY = (0 << 24) /* C2TDELAY */
53 | (0 << 16) /* T2CDELAY */
54 | (0 << 8) /* T2EDELAY */
57 /** - Data Format 0 */
58 mibspiREG5->FMT0 = (0 << 24) /* wdelay */
59 | (0 << 23) /* parity Polarity */
60 | (0 << 22) /* parity enable */
61 | (0 << 21) /* wait on enable */
62 | (0 << 20) /* shift direction */
63 | (0 << 17) /* clock polarity */
64 | (0 << 16) /* clock phase */
65 | (79 << 8) /* baudrate prescale */
66 | 16; /* data word length */
68 /** - Data Format 1 */
69 mibspiREG5->FMT1 = (0 << 24) /* wdelay */
70 | (0 << 23) /* parity Polarity */
71 | (0 << 22) /* parity enable */
72 | (0 << 21) /* wait on enable */
73 | (0 << 20) /* shift direction */
74 | (0 << 17) /* clock polarity */
75 | (0 << 16) /* clock phase */
76 | (79 << 8) /* baudrate prescale */
77 | 16; /* data word length */
79 /** - Data Format 2 */
80 mibspiREG5->FMT2 = (0 << 24) /* wdelay */
81 | (0 << 23) /* parity Polarity */
82 | (0 << 22) /* parity enable */
83 | (0 << 21) /* wait on enable */
84 | (0 << 20) /* shift direction */
85 | (0 << 17) /* clock polarity */
86 | (0 << 16) /* clock phase */
87 | (79 << 8) /* baudrate prescale */
88 | 16; /* data word length */
90 /** - Data Format 3 */
91 mibspiREG5->FMT3 = (0 << 24) /* wdelay */
92 | (0 << 23) /* parity Polarity */
93 | (0 << 22) /* parity enable */
94 | (0 << 21) /* wait on enable */
95 | (0 << 20) /* shift direction */
96 | (0 << 17) /* clock polarity */
97 | (0 << 16) /* clock phase */
98 | (79 << 8) /* baudrate prescale */
99 | 16; /* data word length */
101 /** - wait for buffer inialisation complete before accessing MibSPI registers */
102 while ((mibspiREG5->BUFINIT) != 0) { /* wait */ }
104 /** - inialise transfer groups */
105 mibspiREG5->TGCTRL[0] = (1 << 30) /* oneshot */
106 | (0 << 29) /* pcurrent reset */
107 | (TRG_ALWAYS << 20) /* trigger event */
108 | (TRG_DISABLED << 16) /* trigger source */
109 | (0 << 8); /* start buffer */
111 mibspiREG5->TGCTRL[1] = (1 << 30) /* oneshot */
112 | (0 << 29) /* pcurrent reset */
113 | (TRG_ALWAYS << 20) /* trigger event */
114 | (TRG_DISABLED << 16) /* trigger source */
115 | (8 << 8); /* start buffer */
117 mibspiREG5->TGCTRL[2] = (1 << 30) /* oneshot */
118 | (0 << 29) /* pcurrent reset */
119 | (TRG_ALWAYS << 20) /* trigger event */
120 | (TRG_DISABLED << 16) /* trigger source */
121 | ((8+0) << 8); /* start buffer */
123 mibspiREG5->TGCTRL[3] = (1 << 30) /* oneshot */
124 | (0 << 29) /* pcurrent reset */
125 | (TRG_ALWAYS << 20) /* trigger event */
126 | (TRG_DISABLED << 16) /* trigger source */
127 | ((8+0+0) << 8); /* start buffer */
129 mibspiREG5->TGCTRL[4] = (1 << 30) /* oneshot */
130 | (0 << 29) /* pcurrent reset */
131 | (TRG_ALWAYS << 20) /* trigger event */
132 | (TRG_DISABLED << 16) /* trigger source */
133 | ((8+0+0+0) << 8); /* start buffer */
135 mibspiREG5->TGCTRL[5] = (1 << 30) /* oneshot */
136 | (0 << 29) /* pcurrent reset */
137 | (TRG_ALWAYS << 20) /* trigger event */
138 | (TRG_DISABLED << 16) /* trigger source */
139 | ((8+0+0+0+0) << 8); /* start buffer */
141 mibspiREG5->TGCTRL[6] = (1 << 30) /* oneshot */
142 | (0 << 29) /* pcurrent reset */
143 | (TRG_ALWAYS << 20) /* trigger event */
144 | (TRG_DISABLED << 16) /* trigger source */
145 | ((8+0+0+0+0+0) << 8); /* start buffer */
147 mibspiREG5->TGCTRL[7] = (1 << 30) /* oneshot */
148 | (0 << 29) /* pcurrent reset */
149 | (TRG_ALWAYS << 20) /* trigger event */
150 | (TRG_DISABLED << 16) /* trigger source */
151 | ((8+0+0+0+0+0+0) << 8); /* start buffer */
154 mibspiREG5->TGCTRL[8] = 8+0+0+0+0+0+0+0 << 8;
156 mibspiREG5->LTGPEND = 8+0+0+0+0+0+0+0-1;
158 /** - initalise buffer ram */
165 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
166 | (0 << 12) /* hold chip select Based on Lock selection */
167 | (0 << 11) /* lock transmission */
168 | (0 << 8) /* data format */
169 | CS_0; /* chip select */
171 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
172 | (0 << 12) /* chip select hold */
173 | (0 << 10) /* enable WDELAY */
174 | (0 << 8) /* data format */
175 | CS_0; /* chip select */
181 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
182 | (0 << 12) /* hold chip select Based on Lock selection */
183 | (0 << 11) /* lock transmission */
184 | (0 << 8) /* data format */
185 | CS_1; /* chip select */
187 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
188 | (0 << 12) /* chip select hold */
189 | (0 << 10) /* enable WDELAY */
190 | (0 << 8) /* data format */
191 | CS_1; /* chip select */
197 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
198 | (0 << 12) /* hold chip select Based on Lock selection */
199 | (0 << 11) /* lock transmission */
200 | (0 << 8) /* data format */
201 | CS_2; /* chip select */
203 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
204 | (0 << 12) /* chip select hold */
205 | (0 << 10) /* enable WDELAY */
206 | (0 << 8) /* data format */
207 | CS_2; /* chip select */
211 while (i < 8+0+0+0-1)
213 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
214 | (0 << 12) /* hold chip select Based on Lock selection */
215 | (0 << 11) /* lock transmission */
216 | (0 << 8) /* data format */
217 | CS_3; /* chip select */
219 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
220 | (0 << 12) /* chip select hold */
221 | (0 << 10) /* enable WDELAY */
222 | (0 << 8) /* data format */
223 | CS_3; /* chip select */
227 while (i < 8+0+0+0+0-1)
229 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
230 | (0 << 12) /* hold chip select Based on Lock selection */
231 | (0 << 11) /* lock transmission */
232 | (0 << 8) /* data format */
233 | CS_4; /* chip select */
235 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
236 | (0 << 12) /* chip select hold */
237 | (0 << 10) /* enable WDELAY */
238 | (0 << 8) /* data format */
239 | CS_4; /* chip select */
243 while (i < 8+0+0+0+0+0-1)
245 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
246 | (0 << 12) /* hold chip select Based on Lock selection */
247 | (0 << 11) /* lock transmission */
248 | (0 << 8) /* data format */
249 | CS_5; /* chip select */
251 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
252 | (0 << 12) /* chip select hold */
253 | (0 << 10) /* enable WDELAY */
254 | (0 << 8) /* data format */
255 | CS_5; /* chip select */
259 while (i < 8+0+0+0+0+0+0-1)
261 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
262 | (0 << 12) /* hold chip select Based on Lock selection */
263 | (0 << 11) /* lock transmission */
264 | (0 << 8) /* data format */
265 | CS_6; /* chip select */
267 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
268 | (0 << 12) /* chip select hold */
269 | (0 << 10) /* enable WDELAY */
270 | (0 << 8) /* data format */
271 | CS_6; /* chip select */
275 while (i < 8+0+0+0+0+0+0+0-1)
277 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
278 | (0 << 12) /* hold chip select Based on Lock selection */
279 | (0 << 11) /* lock transmission */
280 | (0 << 8) /* data format */
281 | CS_7; /* chip select */
283 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
284 | (0 << 12) /* chip select hold */
285 | (0 << 10) /* enable WDELAY */
286 | (0 << 8) /* data format */
287 | CS_7; /* chip select */
291 /** - set interrupt levels */
292 mibspiREG5->LVL = (0 << 9) /* TXINT */
293 | (0 << 8) /* RXINT */
294 | (0 << 6) /* OVRNINT */
295 | (0 << 4) /* BITERR */
296 | (0 << 3) /* DESYNC */
297 | (0 << 2) /* PARERR */
298 | (0 << 1) /* TIMEOUT */
301 /** - clear any pending interrupts */
302 mibspiREG5->FLG = 0xFFFFU;
304 /** - enable interrupts */
305 mibspiREG5->INT0 = (0 << 9) /* TXINT */
306 | (0 << 8) /* RXINT */
307 | (0 << 6) /* OVRNINT */
308 | (0 << 4) /* BITERR */
309 | (0 << 3) /* DESYNC */
310 | (0 << 2) /* PARERR */
311 | (0 << 1) /* TIMEOUT */
314 /** @b initalise @b MIBSPI5 @b Port */
316 /** - MIBSPI5 Port output values */
317 mibspiREG5->PCDOUT = 0 /* SCS[0] */
318 | (0 << 1) /* SCS[1] */
319 | (0 << 2) /* SCS[2] */
320 | (0 << 3) /* SCS[3] */
323 | (0 << 10) /* SIMO */
330 | (0 << 11); /* SOMI */
332 /** - MIBSPI5 Port direction */
333 mibspiREG5->PCDIR = 1 /* SCS[0] */
334 | (1 << 1) /* SCS[1] */
335 | (1 << 2) /* SCS[2] */
336 | (1 << 3) /* SCS[3] */
339 | (1 << 10) /* SIMO */
346 | (0 << 11); /* SOMI */
348 /** - MIBSPI5 Port open drain enable */
349 mibspiREG5->PCPDR = 0 /* SCS[0] */
350 | (0 << 1) /* SCS[1] */
351 | (0 << 2) /* SCS[2] */
352 | (0 << 3) /* SCS[3] */
355 | (0 << 10) /* SIMO */
362 | (0 << 11); /* SOMI */
364 /** - MIBSPI5 Port pullup / pulldown selection */
365 mibspiREG5->PCPSL = 1 /* SCS[0] */
366 | (1 << 1) /* SCS[1] */
367 | (1 << 2) /* SCS[2] */
368 | (1 << 3) /* SCS[3] */
371 | (1 << 10) /* SIMO */
378 | (1 << 11); /* SOMI */
380 /** - MIBSPI5 Port pullup / pulldown enable*/
381 mibspiREG5->PCDIS = 0 /* SCS[0] */
382 | (0 << 1) /* SCS[1] */
383 | (0 << 2) /* SCS[2] */
384 | (0 << 3) /* SCS[3] */
387 | (0 << 10) /* SIMO */
394 | (0 << 11); /* SOMI */
396 /* MIBSPI5 set all pins to functional */
397 mibspiREG5->PCFUN = 1 /* SCS[0] */
398 | (1 << 1) /* SCS[1] */
399 | (1 << 2) /* SCS[2] */
400 | (1 << 3) /* SCS[3] */
403 | (1 << 10) /* SIMO */
410 | (1 << 11); /* SOMI */
414 /** - Finaly start MIBSPI5 */
415 mibspiREG5->ENA = 1U;
417 /* USER CODE BEGIN (3) */
423 /** @fn void mibspiSetFunctional(mibspiBASE_t *mibspi, uint32_t port)
424 * @brief Change functional behavoiur of pins at runtime.
425 * @param[in] mibspi - mibspi module base address
426 * @param[in] port - Value to write to PCFUN register
428 * Change the value of the PCFUN register at runtime, this allows to
429 * dynaimcaly change the functionality of the MIBSPI pins between functional
432 void mibspiSetFunctional(mibspiBASE_t *mibspi, uint32_t port)
434 /* USER CODE BEGIN (4) */
437 mibspi->PCFUN = port;
439 /* USER CODE BEGIN (5) */
444 /** @fn void mibspiSetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
445 * @brief Set Buffer Data
446 * @param[in] mibspi - Spi module base address
447 * @param[in] group - Transfer group (0..7)
448 * @param[in] data - new data for transfer group
450 * This function updates the data for the specified transfer group,
451 * the length of the data must match the length of the transfer group.
453 void mibspiSetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
455 /* USER CODE BEGIN (6) */
458 mibspiRAM_t *ram = mibspi == mibspiREG1 ? mibspiRAM1 : (mibspi == mibspiREG3 ? mibspiRAM3 : mibspiRAM5);
459 uint32_t start = (mibspi->TGCTRL[group] >> 8) & 0xFF;
460 uint32_t end = group == 7 ? (mibspi->LTGPEND + 1) : (mibspi->TGCTRL[group+1] >> 8) & 0xFF;
462 if (end < start) {end = 128;}
466 ram->tx[start].data = *data++;
469 /* USER CODE BEGIN (7) */
474 /** @fn void mibspiGetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
475 * @brief Retrieves Buffer Data fro receive buffer
476 * @param[in] mibspi - Spi module base address
477 * @param[in] group - Transfer group (0..7)
478 * @param[out] data - pointer to data array
480 * @return error flags from data buffer, if there was a receive error on
481 * one of the buffers this will be rerflected in the return value.
483 * This function transfers the data from the specified transfer group receve
484 * buffers to the data array, the length of the data must match the length
485 * of the transfer group.
487 uint32_t mibspiGetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
489 /* USER CODE BEGIN (8) */
492 mibspiRAM_t *ram = mibspi == mibspiREG1 ? mibspiRAM1 : (mibspi == mibspiREG3 ? mibspiRAM3 : mibspiRAM5);
493 uint32_t start = (mibspi->TGCTRL[group] >> 8) & 0xFF;
494 uint32_t end = group == 7 ? (mibspi->LTGPEND + 1) : (mibspi->TGCTRL[group+1] >> 8) & 0xFF;
497 if (end < start) {end = 128;}
501 flags |= ram->rx[start].flags;
502 *data++ = ram->rx[start].data;
506 /* USER CODE BEGIN (9) */
509 return (flags >> 8) & 0x5F;
513 /** @fn void mibspiTransfer(mibspiBASE_t *mibspi, uint32_t group)
514 * @brief Transmit Transfer Group
515 * @param[in] mibspi - Spi module base address
516 * @param[in] group - Transfer group (0..7)
518 * Initiates a transfer for the specified transfer group.
520 void mibspiTransfer(mibspiBASE_t *mibspi, uint32_t group)
522 /* USER CODE BEGIN (10) */
525 mibspi->TGCTRL[group] |= 0x80000000;
527 /* USER CODE BEGIN (11) */
532 /** @fn int mibspiIsTransferComplete(mibspiBASE_t *mibspi, uint32_t group)
533 * @brief Check for Transfer Group Ready
534 * @param[in] mibspi - Spi module base address
535 * @param[in] group - Transfer group (0..7)
537 * @return 1 is transfer complete, otherwise 0.
539 * Checks to see if the transfer for the specified transfer group
542 int mibspiIsTransferComplete(mibspiBASE_t *mibspi, uint32_t group)
544 /* USER CODE BEGIN (12) */
546 return (mibspi->INTFLGRDY >> group) & 1;
550 /** @fn void mibspiEnableLoopback(mibspiBASE_t *mibspi, Loopbacktype_t Loopbacktype)
551 * @brief Enable Loopback mode for self test
552 * @param[in] mibspi - Mibspi module base address
553 * @param[in] Loopbacktype - Digital or Analog
555 * This function enables the Loopback mode for self test.
557 void mibspiEnableLoopback(mibspiBASE_t *mibspi, Loopbacktype_t Loopbacktype)
559 /* USER CODE BEGIN (13) */
562 /* Clear Loopback incase enbaled already */
563 mibspi->IOLPKTSTCR = 0;
565 /* Enable Loopback either in Analog or Digital Mode */
566 mibspi->IOLPKTSTCR = 0x00000A00
569 /* USER CODE BEGIN (14) */
573 /** @fn void mibspiDisableLoopback(mibspiBASE_t *mibspi)
574 * @brief Enable Loopback mode for self test
575 * @param[in] mibspi - Mibspi module base address
577 * This function disable the Loopback mode.
579 void mibspiDisableLoopback(mibspiBASE_t *mibspi)
581 /* USER CODE BEGIN (15) */
584 /* Disable Loopback Mode */
585 mibspi->IOLPKTSTCR = 0x000005000;
587 /* USER CODE BEGIN (16) */
592 /** @fn void mibspiEnableGroupNotification(mibspiBASE_t *mibspi, uint32_t group, uint32_t level)
593 * @brief Enable Transfer Group interrupt
594 * @param[in] mibspi - Spi module base address
595 * @param[in] group - Transfer group (0..7)
596 * @param[in] level - Interrupt level
598 * This function enables the transfer group finished interrupt.
600 void mibspiEnableGroupNotification(mibspiBASE_t *mibspi, uint32_t group, uint32_t level)
602 /* USER CODE BEGIN (17) */
607 mibspi->SETINTLVLRDY = 1 << group;
611 mibspi->CLRINTLVLRDY = 1 << group;
613 mibspi->SETINTENARDY = 1 << group;
615 /* USER CODE BEGIN (18) */
620 /** @fn void mibspiDisableGroupNotification(mibspiBASE_t *mibspi, uint32_t group)
621 * @brief Disable Transfer Group interrupt
622 * @param[in] mibspi - Spi module base address
623 * @param[in] group - Transfer group (0..7)
625 * This function disables the transfer group finished interrupt.
627 void mibspiDisableGroupNotification(mibspiBASE_t *mibspi, uint32_t group)
629 /* USER CODE BEGIN (19) */
632 mibspi->CLRINTENARDY = 1 << group;
634 /* USER CODE BEGIN (20) */
640 /** @fn void mibspi5HighLevelInterrupt(void)
641 * @brief Level 0 Interrupt for MIBSPI5
643 #pragma INTERRUPT(mibspi5HighLevelInterrupt, IRQ)
645 void mibspi5HighLevelInterrupt(void)
647 uint32_t vec = mibspiREG5->INTVECT0;
649 /* USER CODE BEGIN (29) */
654 uint32_t flags = mibspiREG5->FLG & (~mibspiREG5->LVL & 0x035F);
655 mibspiREG5->FLG = flags;
656 mibspiNotification(mibspiREG5, flags);
660 mibspiGroupNotification(mibspiREG5, ((vec & 0x3FU) >> 1U) - 1U);
662 /* USER CODE BEGIN (30) */
667 /** @fn void mibspi5LowLevelInterrupt(void)
668 * @brief Level 1 Interrupt for MIBSPI5
670 #pragma INTERRUPT(mibspi5LowLevelInterrupt, IRQ)
672 void mibspi5LowLevelInterrupt(void)
674 uint32_t vec = mibspiREG5->INTVECT1;
676 /* USER CODE BEGIN (31) */
681 uint32_t flags = mibspiREG5->FLG & (mibspiREG5->LVL & 0x035F);
682 mibspiREG5->FLG = flags;
683 mibspiNotification(mibspiREG5, flags);
687 mibspiGroupNotification(mibspiREG5, ((vec & 0x3FU) >> 1U) - 1U);
689 /* USER CODE BEGIN (32) */