2 * @brief MIBSPI Driver Implementation File
8 /* (c) Texas Instruments 2009-2012, All rights reserved. */
12 /** @fn void mibspiInit(void)
13 * @brief Initializes the MIBSPI Driver
15 * This function initializes the MIBSPI module.
21 /** @b intalise @b MIBSPI5 */
23 /** bring MIBSPI out of reset */
24 mibspiREG5->GCR0 = 1U;
26 /** enable MIBSPI RAM Parity */
27 mibspiREG5->EDEN = 0x00000005U;
29 /** enable MIBSPI5 multibuffered mode and enable buffer RAM */
30 mibspiREG5->MIBSPIE = 1U;
32 /** MIBSPI5 master mode and clock configuration */
33 mibspiREG5->GCR1 = (1 << 1) /* CLOKMOD */
36 /** MIBSPI5 enable pin configuration */
37 mibspiREG5->ENAHIGHZ = 0; /* ENABLE HIGHZ */
40 mibspiREG5->DELAY = (0 << 24) /* C2TDELAY */
41 | (0 << 16) /* T2CDELAY */
42 | (0 << 8) /* T2EDELAY */
45 /** - Data Format 0 */
46 mibspiREG5->FMT0 = (0 << 24) /* wdelay */
47 | (0 << 23) /* parity Polarity */
48 | (0 << 22) /* parity enable */
49 | (0 << 21) /* wait on enable */
50 | (0 << 20) /* shift direction */
51 | (0 << 17) /* clock polarity */
52 | (0 << 16) /* clock phase */
53 | ((RPP_VCLK1_FREQ / RPP_MIBSPI_BR_FORMAT0 - 1 ) << 8) /* baudrate prescale */
54 | 16; /* data word length */
56 /** - Data Format 1 */
57 mibspiREG5->FMT1 = (0 << 24) /* wdelay */
58 | (0 << 23) /* parity Polarity */
59 | (0 << 22) /* parity enable */
60 | (0 << 21) /* wait on enable */
61 | (0 << 20) /* shift direction */
62 | (0 << 17) /* clock polarity */
63 | (0 << 16) /* clock phase */
64 | ((RPP_VCLK1_FREQ / RPP_MIBSPI_BR_FORMAT1 - 1 ) << 8) /* baudrate prescale */
65 | 16; /* data word length */
67 /** - Data Format 2 */
68 mibspiREG5->FMT2 = (0 << 24) /* wdelay */
69 | (0 << 23) /* parity Polarity */
70 | (0 << 22) /* parity enable */
71 | (0 << 21) /* wait on enable */
72 | (0 << 20) /* shift direction */
73 | (0 << 17) /* clock polarity */
74 | (0 << 16) /* clock phase */
75 | ((RPP_VCLK1_FREQ / RPP_MIBSPI_BR_FORMAT2 - 1 ) << 8) /* baudrate prescale */
76 | 16; /* data word length */
78 /** - Data Format 3 */
79 mibspiREG5->FMT3 = (0 << 24) /* wdelay */
80 | (0 << 23) /* parity Polarity */
81 | (0 << 22) /* parity enable */
82 | (0 << 21) /* wait on enable */
83 | (0 << 20) /* shift direction */
84 | (0 << 17) /* clock polarity */
85 | (0 << 16) /* clock phase */
86 | ((RPP_VCLK1_FREQ / RPP_MIBSPI_BR_FORMAT3 - 1 ) << 8) /* baudrate prescale */
87 | 16; /* data word length */
89 /** - wait for buffer inialisation complete before accessing MibSPI registers */
90 while ((mibspiREG5->BUFINIT) != 0) { /* wait */ }
92 /** - inialise transfer groups */
93 mibspiREG5->TGCTRL[0] = (1 << 30) /* oneshot */
94 | (0 << 29) /* pcurrent reset */
95 | (TRG_ALWAYS << 20) /* trigger event */
96 | (TRG_DISABLED << 16) /* trigger source */
97 | (0 << 8); /* start buffer */
99 mibspiREG5->TGCTRL[1] = (1 << 30) /* oneshot */
100 | (0 << 29) /* pcurrent reset */
101 | (TRG_ALWAYS << 20) /* trigger event */
102 | (TRG_DISABLED << 16) /* trigger source */
103 | (8 << 8); /* start buffer */
105 mibspiREG5->TGCTRL[2] = (1 << 30) /* oneshot */
106 | (0 << 29) /* pcurrent reset */
107 | (TRG_ALWAYS << 20) /* trigger event */
108 | (TRG_DISABLED << 16) /* trigger source */
109 | ((8+0) << 8); /* start buffer */
111 mibspiREG5->TGCTRL[3] = (1 << 30) /* oneshot */
112 | (0 << 29) /* pcurrent reset */
113 | (TRG_ALWAYS << 20) /* trigger event */
114 | (TRG_DISABLED << 16) /* trigger source */
115 | ((8+0+0) << 8); /* start buffer */
117 mibspiREG5->TGCTRL[4] = (1 << 30) /* oneshot */
118 | (0 << 29) /* pcurrent reset */
119 | (TRG_ALWAYS << 20) /* trigger event */
120 | (TRG_DISABLED << 16) /* trigger source */
121 | ((8+0+0+0) << 8); /* start buffer */
123 mibspiREG5->TGCTRL[5] = (1 << 30) /* oneshot */
124 | (0 << 29) /* pcurrent reset */
125 | (TRG_ALWAYS << 20) /* trigger event */
126 | (TRG_DISABLED << 16) /* trigger source */
127 | ((8+0+0+0+0) << 8); /* start buffer */
129 mibspiREG5->TGCTRL[6] = (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+0+0) << 8); /* start buffer */
135 mibspiREG5->TGCTRL[7] = (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+0+0) << 8); /* start buffer */
142 mibspiREG5->TGCTRL[8] = 8+0+0+0+0+0+0+0 << 8;
144 mibspiREG5->LTGPEND = 8+0+0+0+0+0+0+0-1;
146 /** - initalise buffer ram */
153 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
154 | (0 << 12) /* hold chip select Based on Lock selection */
155 | (0 << 11) /* lock transmission */
156 | (0 << 8) /* data format */
157 | CS_0; /* chip select */
159 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
160 | (0 << 12) /* chip select hold */
161 | (0 << 10) /* enable WDELAY */
162 | (0 << 8) /* data format */
163 | CS_0; /* chip select */
169 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
170 | (0 << 12) /* hold chip select Based on Lock selection */
171 | (0 << 11) /* lock transmission */
172 | (0 << 8) /* data format */
173 | CS_1; /* chip select */
175 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
176 | (0 << 12) /* chip select hold */
177 | (0 << 10) /* enable WDELAY */
178 | (0 << 8) /* data format */
179 | CS_1; /* chip select */
185 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
186 | (0 << 12) /* hold chip select Based on Lock selection */
187 | (0 << 11) /* lock transmission */
188 | (0 << 8) /* data format */
189 | CS_2; /* chip select */
191 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
192 | (0 << 12) /* chip select hold */
193 | (0 << 10) /* enable WDELAY */
194 | (0 << 8) /* data format */
195 | CS_2; /* chip select */
199 while (i < 8+0+0+0-1)
201 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
202 | (0 << 12) /* hold chip select Based on Lock selection */
203 | (0 << 11) /* lock transmission */
204 | (0 << 8) /* data format */
205 | CS_3; /* chip select */
207 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
208 | (0 << 12) /* chip select hold */
209 | (0 << 10) /* enable WDELAY */
210 | (0 << 8) /* data format */
211 | CS_3; /* chip select */
215 while (i < 8+0+0+0+0-1)
217 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
218 | (0 << 12) /* hold chip select Based on Lock selection */
219 | (0 << 11) /* lock transmission */
220 | (0 << 8) /* data format */
221 | CS_4; /* chip select */
223 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
224 | (0 << 12) /* chip select hold */
225 | (0 << 10) /* enable WDELAY */
226 | (0 << 8) /* data format */
227 | CS_4; /* chip select */
231 while (i < 8+0+0+0+0+0-1)
233 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
234 | (0 << 12) /* hold chip select Based on Lock selection */
235 | (0 << 11) /* lock transmission */
236 | (0 << 8) /* data format */
237 | CS_5; /* chip select */
239 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
240 | (0 << 12) /* chip select hold */
241 | (0 << 10) /* enable WDELAY */
242 | (0 << 8) /* data format */
243 | CS_5; /* chip select */
247 while (i < 8+0+0+0+0+0+0-1)
249 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
250 | (0 << 12) /* hold chip select Based on Lock selection */
251 | (0 << 11) /* lock transmission */
252 | (0 << 8) /* data format */
253 | CS_6; /* chip select */
255 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
256 | (0 << 12) /* chip select hold */
257 | (0 << 10) /* enable WDELAY */
258 | (0 << 8) /* data format */
259 | CS_6; /* chip select */
263 while (i < 8+0+0+0+0+0+0+0-1)
265 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
266 | (0 << 12) /* hold chip select Based on Lock selection */
267 | (0 << 11) /* lock transmission */
268 | (0 << 8) /* data format */
269 | CS_7; /* chip select */
271 mibspiRAM5->tx[i++].control = (4 << 13) /* buffer mode */
272 | (0 << 12) /* chip select hold */
273 | (0 << 10) /* enable WDELAY */
274 | (0 << 8) /* data format */
275 | CS_7; /* chip select */
279 /** - set interrupt levels */
280 mibspiREG5->LVL = (0 << 9) /* TXINT */
281 | (0 << 8) /* RXINT */
282 | (0 << 6) /* OVRNINT */
283 | (0 << 4) /* BITERR */
284 | (0 << 3) /* DESYNC */
285 | (0 << 2) /* PARERR */
286 | (0 << 1) /* TIMEOUT */
289 /** - clear any pending interrupts */
290 mibspiREG5->FLG = 0xFFFFU;
292 /** - enable interrupts */
293 mibspiREG5->INT0 = (0 << 9) /* TXINT */
294 | (0 << 8) /* RXINT */
295 | (0 << 6) /* OVRNINT */
296 | (0 << 4) /* BITERR */
297 | (0 << 3) /* DESYNC */
298 | (0 << 2) /* PARERR */
299 | (0 << 1) /* TIMEOUT */
302 /** @b initalise @b MIBSPI5 @b Port */
304 /** - MIBSPI5 Port output values */
305 mibspiREG5->PCDOUT = 0 /* SCS[0] */
306 | (0 << 1) /* SCS[1] */
307 | (0 << 2) /* SCS[2] */
308 | (0 << 3) /* SCS[3] */
311 | (0 << 10) /* SIMO */
318 | (0 << 11); /* SOMI */
320 /** - MIBSPI5 Port direction */
321 mibspiREG5->PCDIR = 1 /* SCS[0] */
322 | (1 << 1) /* SCS[1] */
323 | (1 << 2) /* SCS[2] */
324 | (1 << 3) /* SCS[3] */
327 | (1 << 10) /* SIMO */
334 | (0 << 11); /* SOMI */
336 /** - MIBSPI5 Port open drain enable */
337 mibspiREG5->PCPDR = 0 /* SCS[0] */
338 | (0 << 1) /* SCS[1] */
339 | (0 << 2) /* SCS[2] */
340 | (0 << 3) /* SCS[3] */
343 | (0 << 10) /* SIMO */
350 | (0 << 11); /* SOMI */
352 /** - MIBSPI5 Port pullup / pulldown selection */
353 mibspiREG5->PCPSL = 1 /* SCS[0] */
354 | (1 << 1) /* SCS[1] */
355 | (1 << 2) /* SCS[2] */
356 | (1 << 3) /* SCS[3] */
359 | (1 << 10) /* SIMO */
366 | (1 << 11); /* SOMI */
368 /** - MIBSPI5 Port pullup / pulldown enable*/
369 mibspiREG5->PCDIS = 0 /* SCS[0] */
370 | (0 << 1) /* SCS[1] */
371 | (0 << 2) /* SCS[2] */
372 | (0 << 3) /* SCS[3] */
375 | (0 << 10) /* SIMO */
382 | (0 << 11); /* SOMI */
384 /* MIBSPI5 set all pins to functional */
385 mibspiREG5->PCFUN = 1 /* SCS[0] */
386 | (1 << 1) /* SCS[1] */
387 | (1 << 2) /* SCS[2] */
388 | (1 << 3) /* SCS[3] */
391 | (1 << 10) /* SIMO */
398 | (1 << 11); /* SOMI */
402 /** - Finaly start MIBSPI5 */
403 mibspiREG5->ENA = 1U;
407 /** @fn void mibspiSetFunctional(mibspiBASE_t *mibspi, uint32_t port)
408 * @brief Change functional behavoiur of pins at runtime.
409 * @param[in] mibspi - mibspi module base address
410 * @param[in] port - Value to write to PCFUN register
412 * Change the value of the PCFUN register at runtime, this allows to
413 * dynaimcaly change the functionality of the MIBSPI pins between functional
416 void mibspiSetFunctional(mibspiBASE_t *mibspi, uint32_t port)
418 mibspi->PCFUN = port;
422 /** @fn void mibspiSetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
423 * @brief Set Buffer Data
424 * @param[in] mibspi - Spi module base address
425 * @param[in] group - Transfer group (0..7)
426 * @param[in] data - new data for transfer group
428 * This function updates the data for the specified transfer group,
429 * the length of the data must match the length of the transfer group.
431 void mibspiSetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
433 mibspiRAM_t *ram = mibspi == mibspiREG1 ? mibspiRAM1 : (mibspi == mibspiREG3 ? mibspiRAM3 : mibspiRAM5);
434 uint32_t start = (mibspi->TGCTRL[group] >> 8) & 0xFF;
435 uint32_t end = group == 7 ? (mibspi->LTGPEND + 1) : (mibspi->TGCTRL[group+1] >> 8) & 0xFF;
437 if (end < start) {end = 128;}
441 ram->tx[start].data = *data++;
447 /** @fn void mibspiGetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
448 * @brief Retrieves Buffer Data fro receive buffer
449 * @param[in] mibspi - Spi module base address
450 * @param[in] group - Transfer group (0..7)
451 * @param[out] data - pointer to data array
453 * @return error flags from data buffer, if there was a receive error on
454 * one of the buffers this will be rerflected in the return value.
456 * This function transfers the data from the specified transfer group receve
457 * buffers to the data array, the length of the data must match the length
458 * of the transfer group.
460 uint32_t mibspiGetData(mibspiBASE_t *mibspi, uint32_t group, uint16_t data[])
462 mibspiRAM_t *ram = mibspi == mibspiREG1 ? mibspiRAM1 : (mibspi == mibspiREG3 ? mibspiRAM3 : mibspiRAM5);
463 uint32_t start = (mibspi->TGCTRL[group] >> 8) & 0xFF;
464 uint32_t end = group == 7 ? (mibspi->LTGPEND + 1) : (mibspi->TGCTRL[group+1] >> 8) & 0xFF;
467 if (end < start) {end = 128;}
471 flags |= ram->rx[start].flags;
472 *data++ = ram->rx[start].data;
476 return (flags >> 8) & 0x5F;
480 /** @fn void mibspiTransfer(mibspiBASE_t *mibspi, uint32_t group)
481 * @brief Transmit Transfer Group
482 * @param[in] mibspi - Spi module base address
483 * @param[in] group - Transfer group (0..7)
485 * Initiates a transfer for the specified transfer group.
487 void mibspiTransfer(mibspiBASE_t *mibspi, uint32_t group)
489 mibspi->TGCTRL[group] |= 0x80000000;
493 /** @fn int mibspiIsTransferComplete(mibspiBASE_t *mibspi, uint32_t group)
494 * @brief Check for Transfer Group Ready
495 * @param[in] mibspi - Spi module base address
496 * @param[in] group - Transfer group (0..7)
498 * @return 1 is transfer complete, otherwise 0.
500 * Checks to see if the transfer for the specified transfer group
503 int mibspiIsTransferComplete(mibspiBASE_t *mibspi, uint32_t group)
505 return (mibspi->INTFLGRDY >> group) & 1;
509 /** @fn void mibspiEnableLoopback(mibspiBASE_t *mibspi, Loopbacktype_t Loopbacktype)
510 * @brief Enable Loopback mode for self test
511 * @param[in] mibspi - Mibspi module base address
512 * @param[in] Loopbacktype - Digital or Analog
514 * This function enables the Loopback mode for self test.
516 void mibspiEnableLoopback(mibspiBASE_t *mibspi, Loopbacktype_t Loopbacktype)
518 /* Clear Loopback incase enbaled already */
519 mibspi->IOLPKTSTCR = 0;
521 /* Enable Loopback either in Analog or Digital Mode */
522 mibspi->IOLPKTSTCR = 0x00000A00
526 /** @fn void mibspiDisableLoopback(mibspiBASE_t *mibspi)
527 * @brief Enable Loopback mode for self test
528 * @param[in] mibspi - Mibspi module base address
530 * This function disable the Loopback mode.
532 void mibspiDisableLoopback(mibspiBASE_t *mibspi)
534 /* Disable Loopback Mode */
535 mibspi->IOLPKTSTCR = 0x000005000;
539 /** @fn void mibspiEnableGroupNotification(mibspiBASE_t *mibspi, uint32_t group, uint32_t level)
540 * @brief Enable Transfer Group interrupt
541 * @param[in] mibspi - Spi module base address
542 * @param[in] group - Transfer group (0..7)
543 * @param[in] level - Interrupt level
545 * This function enables the transfer group finished interrupt.
547 void mibspiEnableGroupNotification(mibspiBASE_t *mibspi, uint32_t group, uint32_t level)
551 mibspi->SETINTLVLRDY = 1 << group;
555 mibspi->CLRINTLVLRDY = 1 << group;
557 mibspi->SETINTENARDY = 1 << group;
561 /** @fn void mibspiDisableGroupNotification(mibspiBASE_t *mibspi, uint32_t group)
562 * @brief Disable Transfer Group interrupt
563 * @param[in] mibspi - Spi module base address
564 * @param[in] group - Transfer group (0..7)
566 * This function disables the transfer group finished interrupt.
568 void mibspiDisableGroupNotification(mibspiBASE_t *mibspi, uint32_t group)
570 mibspi->CLRINTENARDY = 1 << group;