ssi.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. //*****************************************************************************
  2. //
  3. // ssi.c - Driver for Synchronous Serial Interface.
  4. //
  5. // Copyright (c) 2005-2014 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above copyright
  16. // notice, this list of conditions and the following disclaimer in the
  17. // documentation and/or other materials provided with the
  18. // distribution.
  19. //
  20. // Neither the name of Texas Instruments Incorporated nor the names of
  21. // its contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. // This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library.
  37. //
  38. //*****************************************************************************
  39. //*****************************************************************************
  40. //
  41. //! \addtogroup ssi_api
  42. //! @{
  43. //
  44. //*****************************************************************************
  45. #include <stdbool.h>
  46. #include <stdint.h>
  47. #include "inc/hw_ints.h"
  48. #include "inc/hw_memmap.h"
  49. #include "inc/hw_ssi.h"
  50. #include "inc/hw_sysctl.h"
  51. #include "inc/hw_types.h"
  52. #include "driverlib/debug.h"
  53. #include "driverlib/interrupt.h"
  54. #include "driverlib/ssi.h"
  55. //*****************************************************************************
  56. //
  57. // A mapping of timer base address to interrupt number.
  58. //
  59. //*****************************************************************************
  60. static const uint32_t g_ppui32SSIIntMap[][2] =
  61. {
  62. { SSI0_BASE, INT_SSI0_TM4C123 },
  63. { SSI1_BASE, INT_SSI1_TM4C123 },
  64. { SSI2_BASE, INT_SSI2_TM4C123 },
  65. { SSI3_BASE, INT_SSI3_TM4C123 },
  66. };
  67. static const uint_fast8_t g_ui8SSIIntMapRows =
  68. sizeof(g_ppui32SSIIntMap) / sizeof(g_ppui32SSIIntMap[0]);
  69. static const uint32_t g_ppui32SSIIntMapSnowflake[][2] =
  70. {
  71. { SSI0_BASE, INT_SSI0_TM4C129 },
  72. { SSI1_BASE, INT_SSI1_TM4C129 },
  73. { SSI2_BASE, INT_SSI2_TM4C129 },
  74. { SSI3_BASE, INT_SSI3_TM4C129 },
  75. };
  76. static const uint_fast8_t g_ui8SSIIntMapSnowflakeRows =
  77. sizeof(g_ppui32SSIIntMapSnowflake) / sizeof(g_ppui32SSIIntMapSnowflake[0]);
  78. //*****************************************************************************
  79. //
  80. //! \internal
  81. //! Checks an SSI base address.
  82. //!
  83. //! \param ui32Base specifies the SSI module base address.
  84. //!
  85. //! This function determines if a SSI module base address is valid.
  86. //!
  87. //! \return Returns \b true if the base address is valid and \b false
  88. //! otherwise.
  89. //
  90. //*****************************************************************************
  91. #ifdef DEBUG
  92. static bool
  93. _SSIBaseValid(uint32_t ui32Base)
  94. {
  95. return((ui32Base == SSI0_BASE) || (ui32Base == SSI1_BASE) ||
  96. (ui32Base == SSI2_BASE) || (ui32Base == SSI3_BASE));
  97. }
  98. #endif
  99. //*****************************************************************************
  100. //
  101. //! Returns the interrupt number of SSI module .
  102. //!
  103. //! \param ui32Base is the base address of the SSI module.
  104. //!
  105. //! This function returns the interrupt number for the SSI module with the base
  106. //! address passed in the \e ui32Base parameter.
  107. //!
  108. //! \return Returns an SSI interrupt number, or 0 if the interrupt does not
  109. //! exist.
  110. //
  111. //*****************************************************************************
  112. static uint32_t
  113. _SSIIntNumberGet(uint32_t ui32Base)
  114. {
  115. uint_fast8_t ui8Idx, ui8Rows;
  116. const uint32_t (*ppui32SSIIntMap)[2];
  117. //
  118. // Check the arguments.
  119. //
  120. ASSERT(_SSIBaseValid(ui32Base));
  121. ppui32SSIIntMap = g_ppui32SSIIntMap;
  122. ui8Rows = g_ui8SSIIntMapRows;
  123. if(CLASS_IS_TM4C129)
  124. {
  125. ppui32SSIIntMap = g_ppui32SSIIntMapSnowflake;
  126. ui8Rows = g_ui8SSIIntMapSnowflakeRows;
  127. }
  128. //
  129. // Loop through the table that maps SSI base addresses to interrupt
  130. // numbers.
  131. //
  132. for(ui8Idx = 0; ui8Idx < ui8Rows; ui8Idx++)
  133. {
  134. //
  135. // See if this base address matches.
  136. //
  137. if(ppui32SSIIntMap[ui8Idx][0] == ui32Base)
  138. {
  139. //
  140. // Return the corresponding interrupt number.
  141. //
  142. return(ppui32SSIIntMap[ui8Idx][1]);
  143. }
  144. }
  145. //
  146. // The base address could not be found, so return an error.
  147. //
  148. return(0);
  149. }
  150. //*****************************************************************************
  151. //
  152. //! Configures the synchronous serial interface.
  153. //!
  154. //! \param ui32Base specifies the SSI module base address.
  155. //! \param ui32SSIClk is the rate of the clock supplied to the SSI module.
  156. //! \param ui32Protocol specifies the data transfer protocol.
  157. //! \param ui32Mode specifies the mode of operation.
  158. //! \param ui32BitRate specifies the clock rate.
  159. //! \param ui32DataWidth specifies number of bits transferred per frame.
  160. //!
  161. //! This function configures the synchronous serial interface. It sets
  162. //! the SSI protocol, mode of operation, bit rate, and data width.
  163. //!
  164. //! The \e ui32Protocol parameter defines the data frame format. The
  165. //! \e ui32Protocol parameter can be one of the following values:
  166. //! \b SSI_FRF_MOTO_MODE_0, \b SSI_FRF_MOTO_MODE_1, \b SSI_FRF_MOTO_MODE_2,
  167. //! \b SSI_FRF_MOTO_MODE_3, \b SSI_FRF_TI, or \b SSI_FRF_NMW. Note that
  168. //! the \b SSI_FRF_NMW option is only available on some devices. Refer to the
  169. //! device data sheet to determine if the Microwire format is supported on
  170. //! a particular device. The Motorola frame formats encode the following
  171. //! polarity and phase configurations:
  172. //!
  173. //! <pre>
  174. //! Polarity Phase Mode
  175. //! 0 0 SSI_FRF_MOTO_MODE_0
  176. //! 0 1 SSI_FRF_MOTO_MODE_1
  177. //! 1 0 SSI_FRF_MOTO_MODE_2
  178. //! 1 1 SSI_FRF_MOTO_MODE_3
  179. //! </pre>
  180. //!
  181. //! The \e ui32Mode parameter defines the operating mode of the SSI module.
  182. //! The SSI module can operate as a master or slave; if it is a slave, the SSI
  183. //! can be configured to disable output on its serial output line. The
  184. //! \e ui32Mode parameter can be one of the following values:
  185. //! \b SSI_MODE_MASTER, \b SSI_MODE_SLAVE, or \b SSI_MODE_SLAVE_OD.
  186. //!
  187. //! The \e ui32BitRate parameter defines the bit rate for the SSI. This bit
  188. //! rate must satisfy the following clock ratio criteria:
  189. //!
  190. //! - FSSI >= 2 * bit rate (master mode)
  191. //! - FSSI >= 12 * bit rate (slave modes)
  192. //!
  193. //! where FSSI is the frequency of the clock supplied to the SSI module. Note
  194. //! that there are frequency limits for FSSI that are described in the Bit Rate
  195. //! Generation section of the SSI chapter in the data sheet.
  196. //!
  197. //! The \e ui32DataWidth parameter defines the width of the data transfers and
  198. //! can be a value between 4 and 16, inclusive.
  199. //!
  200. //! The peripheral clock is the same as the processor clock. This value is
  201. //! returned by SysCtlClockGet(), or it can be explicitly hard coded if it is
  202. //! constant and known (to save the code/execution overhead of a call to
  203. //! SysCtlClockGet()).
  204. //!
  205. //! \return None.
  206. //
  207. //*****************************************************************************
  208. void
  209. SSIConfigSetExpClk(uint32_t ui32Base, uint32_t ui32SSIClk,
  210. uint32_t ui32Protocol, uint32_t ui32Mode,
  211. uint32_t ui32BitRate, uint32_t ui32DataWidth)
  212. {
  213. uint32_t ui32MaxBitRate;
  214. uint32_t ui32RegVal;
  215. uint32_t ui32PreDiv;
  216. uint32_t ui32SCR;
  217. uint32_t ui32SPH_SPO;
  218. //
  219. // Check the arguments.
  220. //
  221. ASSERT(_SSIBaseValid(ui32Base));
  222. ASSERT((ui32Protocol == SSI_FRF_MOTO_MODE_0) ||
  223. (ui32Protocol == SSI_FRF_MOTO_MODE_1) ||
  224. (ui32Protocol == SSI_FRF_MOTO_MODE_2) ||
  225. (ui32Protocol == SSI_FRF_MOTO_MODE_3) ||
  226. (ui32Protocol == SSI_FRF_TI) ||
  227. (ui32Protocol == SSI_FRF_NMW));
  228. ASSERT((ui32Mode == SSI_MODE_MASTER) ||
  229. (ui32Mode == SSI_MODE_SLAVE) ||
  230. (ui32Mode == SSI_MODE_SLAVE_OD));
  231. ASSERT(((ui32Mode == SSI_MODE_MASTER) &&
  232. (ui32BitRate <= (ui32SSIClk / 2))) ||
  233. ((ui32Mode != SSI_MODE_MASTER) &&
  234. (ui32BitRate <= (ui32SSIClk / 12))));
  235. ASSERT((ui32SSIClk / ui32BitRate) <= (254 * 256));
  236. ASSERT((ui32DataWidth >= 4) && (ui32DataWidth <= 16));
  237. //
  238. // Set the mode.
  239. //
  240. ui32RegVal = (ui32Mode == SSI_MODE_SLAVE_OD) ? SSI_CR1_SOD : 0;
  241. ui32RegVal |= (ui32Mode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS;
  242. HWREG(ui32Base + SSI_O_CR1) = ui32RegVal;
  243. //
  244. // Set the clock predivider.
  245. //
  246. ui32MaxBitRate = ui32SSIClk / ui32BitRate;
  247. ui32PreDiv = 0;
  248. do
  249. {
  250. ui32PreDiv += 2;
  251. ui32SCR = (ui32MaxBitRate / ui32PreDiv) - 1;
  252. }
  253. while(ui32SCR > 255);
  254. HWREG(ui32Base + SSI_O_CPSR) = ui32PreDiv;
  255. //
  256. // Set protocol and clock rate.
  257. //
  258. ui32SPH_SPO = (ui32Protocol & 3) << 6;
  259. ui32Protocol &= SSI_CR0_FRF_M;
  260. ui32RegVal = (ui32SCR << 8) | ui32SPH_SPO | ui32Protocol |
  261. (ui32DataWidth - 1);
  262. HWREG(ui32Base + SSI_O_CR0) = ui32RegVal;
  263. }
  264. //*****************************************************************************
  265. //
  266. //! Enables the synchronous serial interface.
  267. //!
  268. //! \param ui32Base specifies the SSI module base address.
  269. //!
  270. //! This function enables operation of the synchronous serial interface. The
  271. //! synchronous serial interface must be configured before it is enabled.
  272. //!
  273. //! \return None.
  274. //
  275. //*****************************************************************************
  276. void
  277. SSIEnable(uint32_t ui32Base)
  278. {
  279. //
  280. // Check the arguments.
  281. //
  282. ASSERT(_SSIBaseValid(ui32Base));
  283. //
  284. // Read-modify-write the enable bit.
  285. //
  286. HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_SSE;
  287. }
  288. //*****************************************************************************
  289. //
  290. //! Disables the synchronous serial interface.
  291. //!
  292. //! \param ui32Base specifies the SSI module base address.
  293. //!
  294. //! This function disables operation of the synchronous serial interface.
  295. //!
  296. //! \return None.
  297. //
  298. //*****************************************************************************
  299. void
  300. SSIDisable(uint32_t ui32Base)
  301. {
  302. //
  303. // Check the arguments.
  304. //
  305. ASSERT(_SSIBaseValid(ui32Base));
  306. //
  307. // Read-modify-write the enable bit.
  308. //
  309. HWREG(ui32Base + SSI_O_CR1) &= ~(SSI_CR1_SSE);
  310. }
  311. //*****************************************************************************
  312. //
  313. //! Registers an interrupt handler for the synchronous serial interface.
  314. //!
  315. //! \param ui32Base specifies the SSI module base address.
  316. //! \param pfnHandler is a pointer to the function to be called when the
  317. //! synchronous serial interface interrupt occurs.
  318. //!
  319. //! This function registers the handler to be called when an SSI interrupt
  320. //! occurs. This function enables the global interrupt in the interrupt
  321. //! controller; specific SSI interrupts must be enabled via SSIIntEnable(). If
  322. //! necessary, it is the interrupt handler's responsibility to clear the
  323. //! interrupt source via SSIIntClear().
  324. //!
  325. //! \sa IntRegister() for important information about registering interrupt
  326. //! handlers.
  327. //!
  328. //! \return None.
  329. //
  330. //*****************************************************************************
  331. void
  332. SSIIntRegister(uint32_t ui32Base, void (*pfnHandler)(void))
  333. {
  334. uint32_t ui32Int;
  335. //
  336. // Check the arguments.
  337. //
  338. ASSERT(_SSIBaseValid(ui32Base));
  339. //
  340. // Determine the interrupt number based on the SSI module.
  341. //
  342. ui32Int = _SSIIntNumberGet(ui32Base);
  343. ASSERT(ui32Int != 0);
  344. //
  345. // Register the interrupt handler, returning an error if an error occurs.
  346. //
  347. IntRegister(ui32Int, pfnHandler);
  348. //
  349. // Enable the synchronous serial interface interrupt.
  350. //
  351. IntEnable(ui32Int);
  352. }
  353. //*****************************************************************************
  354. //
  355. //! Unregisters an interrupt handler for the synchronous serial interface.
  356. //!
  357. //! \param ui32Base specifies the SSI module base address.
  358. //!
  359. //! This function clears the handler to be called when an SSI interrupt
  360. //! occurs. This function also masks off the interrupt in the interrupt
  361. //! controller so that the interrupt handler no longer is called.
  362. //!
  363. //! \sa IntRegister() for important information about registering interrupt
  364. //! handlers.
  365. //!
  366. //! \return None.
  367. //
  368. //*****************************************************************************
  369. void
  370. SSIIntUnregister(uint32_t ui32Base)
  371. {
  372. uint32_t ui32Int;
  373. //
  374. // Check the arguments.
  375. //
  376. ASSERT(_SSIBaseValid(ui32Base));
  377. //
  378. // Determine the interrupt number based on the SSI module.
  379. //
  380. ui32Int = _SSIIntNumberGet(ui32Base);
  381. ASSERT(ui32Int != 0);
  382. //
  383. // Disable the interrupt.
  384. //
  385. IntDisable(ui32Int);
  386. //
  387. // Unregister the interrupt handler.
  388. //
  389. IntUnregister(ui32Int);
  390. }
  391. //*****************************************************************************
  392. //
  393. //! Enables individual SSI interrupt sources.
  394. //!
  395. //! \param ui32Base specifies the SSI module base address.
  396. //! \param ui32IntFlags is a bit mask of the interrupt sources to be enabled.
  397. //!
  398. //! This function enables the indicated SSI interrupt sources. Only the
  399. //! sources that are enabled can be reflected to the processor interrupt;
  400. //! disabled sources have no effect on the processor. The \e ui32IntFlags
  401. //! parameter can be any of the \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, or
  402. //! \b SSI_RXOR values.
  403. //!
  404. //! \return None.
  405. //
  406. //*****************************************************************************
  407. void
  408. SSIIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
  409. {
  410. //
  411. // Check the arguments.
  412. //
  413. ASSERT(_SSIBaseValid(ui32Base));
  414. //
  415. // Enable the specified interrupts.
  416. //
  417. HWREG(ui32Base + SSI_O_IM) |= ui32IntFlags;
  418. }
  419. //*****************************************************************************
  420. //
  421. //! Disables individual SSI interrupt sources.
  422. //!
  423. //! \param ui32Base specifies the SSI module base address.
  424. //! \param ui32IntFlags is a bit mask of the interrupt sources to be disabled.
  425. //!
  426. //! This function disables the indicated SSI interrupt sources. The
  427. //! \e ui32IntFlags parameter can be any of the \b SSI_TXFF, \b SSI_RXFF,
  428. //! \b SSI_RXTO, or \b SSI_RXOR values.
  429. //!
  430. //! \return None.
  431. //
  432. //*****************************************************************************
  433. void
  434. SSIIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags)
  435. {
  436. //
  437. // Check the arguments.
  438. //
  439. ASSERT(_SSIBaseValid(ui32Base));
  440. //
  441. // Disable the specified interrupts.
  442. //
  443. HWREG(ui32Base + SSI_O_IM) &= ~(ui32IntFlags);
  444. }
  445. //*****************************************************************************
  446. //
  447. //! Gets the current interrupt status.
  448. //!
  449. //! \param ui32Base specifies the SSI module base address.
  450. //! \param bMasked is \b false if the raw interrupt status is required or
  451. //! \b true if the masked interrupt status is required.
  452. //!
  453. //! This function returns the interrupt status for the SSI module. Either the
  454. //! raw interrupt status or the status of interrupts that are allowed to
  455. //! reflect to the processor can be returned.
  456. //!
  457. //! \return The current interrupt status, enumerated as a bit field of
  458. //! \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, and \b SSI_RXOR.
  459. //
  460. //*****************************************************************************
  461. uint32_t
  462. SSIIntStatus(uint32_t ui32Base, bool bMasked)
  463. {
  464. //
  465. // Check the arguments.
  466. //
  467. ASSERT(_SSIBaseValid(ui32Base));
  468. //
  469. // Return either the interrupt status or the raw interrupt status as
  470. // requested.
  471. //
  472. if(bMasked)
  473. {
  474. return(HWREG(ui32Base + SSI_O_MIS));
  475. }
  476. else
  477. {
  478. return(HWREG(ui32Base + SSI_O_RIS));
  479. }
  480. }
  481. //*****************************************************************************
  482. //
  483. //! Clears SSI interrupt sources.
  484. //!
  485. //! \param ui32Base specifies the SSI module base address.
  486. //! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared.
  487. //!
  488. //! This function clears the specified SSI interrupt sources so that they no
  489. //! longer assert. This function must be called in the interrupt handler to
  490. //! keep the interrupts from being triggered again immediately upon exit. The
  491. //! \e ui32IntFlags parameter can consist of either or both the \b SSI_RXTO and
  492. //! \b SSI_RXOR values.
  493. //!
  494. //! \note Because there is a write buffer in the Cortex-M processor, it may
  495. //! take several clock cycles before the interrupt source is actually cleared.
  496. //! Therefore, it is recommended that the interrupt source be cleared early in
  497. //! the interrupt handler (as opposed to the very last action) to avoid
  498. //! returning from the interrupt handler before the interrupt source is
  499. //! actually cleared. Failure to do so may result in the interrupt handler
  500. //! being immediately reentered (because the interrupt controller still sees
  501. //! the interrupt source asserted).
  502. //!
  503. //! \return None.
  504. //
  505. //*****************************************************************************
  506. void
  507. SSIIntClear(uint32_t ui32Base, uint32_t ui32IntFlags)
  508. {
  509. //
  510. // Check the arguments.
  511. //
  512. ASSERT(_SSIBaseValid(ui32Base));
  513. //
  514. // Clear the requested interrupt sources.
  515. //
  516. HWREG(ui32Base + SSI_O_ICR) = ui32IntFlags;
  517. }
  518. //*****************************************************************************
  519. //
  520. //! Puts a data element into the SSI transmit FIFO.
  521. //!
  522. //! \param ui32Base specifies the SSI module base address.
  523. //! \param ui32Data is the data to be transmitted over the SSI interface.
  524. //!
  525. //! This function places the supplied data into the transmit FIFO of the
  526. //! specified SSI module. If there is no space available in the transmit FIFO,
  527. //! this function waits until there is space available before returning.
  528. //!
  529. //! \note The upper 32 - N bits of \e ui32Data are discarded by the hardware,
  530. //! where N is the data width as configured by SSIConfigSetExpClk(). For
  531. //! example, if the interface is configured for 8-bit data width, the upper 24
  532. //! bits of \e ui32Data are discarded.
  533. //!
  534. //! \return None.
  535. //
  536. //*****************************************************************************
  537. void
  538. SSIDataPut(uint32_t ui32Base, uint32_t ui32Data)
  539. {
  540. //
  541. // Check the arguments.
  542. //
  543. ASSERT(_SSIBaseValid(ui32Base));
  544. ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) &
  545. SSI_CR0_DSS_M))) == 0);
  546. //
  547. // Wait until there is space.
  548. //
  549. while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF))
  550. {
  551. }
  552. //
  553. // Write the data to the SSI.
  554. //
  555. HWREG(ui32Base + SSI_O_DR) = ui32Data;
  556. }
  557. //*****************************************************************************
  558. //
  559. //! Puts a data element into the SSI transmit FIFO.
  560. //!
  561. //! \param ui32Base specifies the SSI module base address.
  562. //! \param ui32Data is the data to be transmitted over the SSI interface.
  563. //!
  564. //! This function places the supplied data into the transmit FIFO of the
  565. //! specified SSI module. If there is no space in the FIFO, then this function
  566. //! returns a zero.
  567. //!
  568. //! \note The upper 32 - N bits of \e ui32Data are discarded by the hardware,
  569. //! where N is the data width as configured by SSIConfigSetExpClk(). For
  570. //! example, if the interface is configured for 8-bit data width, the upper 24
  571. //! bits of \e ui32Data are discarded.
  572. //!
  573. //! \return Returns the number of elements written to the SSI transmit FIFO.
  574. //
  575. //*****************************************************************************
  576. int32_t
  577. SSIDataPutNonBlocking(uint32_t ui32Base, uint32_t ui32Data)
  578. {
  579. //
  580. // Check the arguments.
  581. //
  582. ASSERT(_SSIBaseValid(ui32Base));
  583. ASSERT((ui32Data & (0xfffffffe << (HWREG(ui32Base + SSI_O_CR0) &
  584. SSI_CR0_DSS_M))) == 0);
  585. //
  586. // Check for space to write.
  587. //
  588. if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF)
  589. {
  590. HWREG(ui32Base + SSI_O_DR) = ui32Data;
  591. return(1);
  592. }
  593. else
  594. {
  595. return(0);
  596. }
  597. }
  598. //*****************************************************************************
  599. //
  600. //! Gets a data element from the SSI receive FIFO.
  601. //!
  602. //! \param ui32Base specifies the SSI module base address.
  603. //! \param pui32Data is a pointer to a storage location for data that was
  604. //! received over the SSI interface.
  605. //!
  606. //! This function gets received data from the receive FIFO of the specified
  607. //! SSI module and places that data into the location specified by the
  608. //! \e pui32Data parameter. If there is no data available, this function waits
  609. //! until data is received before returning.
  610. //!
  611. //! \note Only the lower N bits of the value written to \e pui32Data contain
  612. //! valid data, where N is the data width as configured by
  613. //! SSIConfigSetExpClk(). For example, if the interface is configured for
  614. //! 8-bit data width, only the lower 8 bits of the value written to
  615. //! \e pui32Data contain valid data.
  616. //!
  617. //! \return None.
  618. //
  619. //*****************************************************************************
  620. void
  621. SSIDataGet(uint32_t ui32Base, uint32_t *pui32Data)
  622. {
  623. //
  624. // Check the arguments.
  625. //
  626. ASSERT(_SSIBaseValid(ui32Base));
  627. //
  628. // Wait until there is data to be read.
  629. //
  630. while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_RNE))
  631. {
  632. }
  633. //
  634. // Read data from SSI.
  635. //
  636. *pui32Data = HWREG(ui32Base + SSI_O_DR);
  637. }
  638. //*****************************************************************************
  639. //
  640. //! Gets a data element from the SSI receive FIFO.
  641. //!
  642. //! \param ui32Base specifies the SSI module base address.
  643. //! \param pui32Data is a pointer to a storage location for data that was
  644. //! received over the SSI interface.
  645. //!
  646. //! This function gets received data from the receive FIFO of the specified SSI
  647. //! module and places that data into the location specified by the \e ui32Data
  648. //! parameter. If there is no data in the FIFO, then this function returns a
  649. //! zero.
  650. //!
  651. //! \note Only the lower N bits of the value written to \e pui32Data contain
  652. //! valid data, where N is the data width as configured by
  653. //! SSIConfigSetExpClk(). For example, if the interface is configured for
  654. //! 8-bit data width, only the lower 8 bits of the value written to
  655. //! \e pui32Data contain valid data.
  656. //!
  657. //! \return Returns the number of elements read from the SSI receive FIFO.
  658. //
  659. //*****************************************************************************
  660. int32_t
  661. SSIDataGetNonBlocking(uint32_t ui32Base, uint32_t *pui32Data)
  662. {
  663. //
  664. // Check the arguments.
  665. //
  666. ASSERT(_SSIBaseValid(ui32Base));
  667. //
  668. // Check for data to read.
  669. //
  670. if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_RNE)
  671. {
  672. *pui32Data = HWREG(ui32Base + SSI_O_DR);
  673. return(1);
  674. }
  675. else
  676. {
  677. return(0);
  678. }
  679. }
  680. //*****************************************************************************
  681. //
  682. //! Enables SSI DMA operation.
  683. //!
  684. //! \param ui32Base is the base address of the SSI module.
  685. //! \param ui32DMAFlags is a bit mask of the DMA features to enable.
  686. //!
  687. //! This function enables the specified SSI DMA features. The SSI can be
  688. //! configured to use DMA for transmit and/or receive data transfers.
  689. //! The \e ui32DMAFlags parameter is the logical OR of any of the following
  690. //! values:
  691. //!
  692. //! - SSI_DMA_RX - enable DMA for receive
  693. //! - SSI_DMA_TX - enable DMA for transmit
  694. //!
  695. //! \note The uDMA controller must also be set up before DMA can be used
  696. //! with the SSI.
  697. //!
  698. //! \return None.
  699. //
  700. //*****************************************************************************
  701. void
  702. SSIDMAEnable(uint32_t ui32Base, uint32_t ui32DMAFlags)
  703. {
  704. //
  705. // Check the arguments.
  706. //
  707. ASSERT(_SSIBaseValid(ui32Base));
  708. //
  709. // Set the requested bits in the SSI DMA control register.
  710. //
  711. HWREG(ui32Base + SSI_O_DMACTL) |= ui32DMAFlags;
  712. }
  713. //*****************************************************************************
  714. //
  715. //! Disables SSI DMA operation.
  716. //!
  717. //! \param ui32Base is the base address of the SSI module.
  718. //! \param ui32DMAFlags is a bit mask of the DMA features to disable.
  719. //!
  720. //! This function is used to disable SSI DMA features that were enabled
  721. //! by SSIDMAEnable(). The specified SSI DMA features are disabled. The
  722. //! \e ui32DMAFlags parameter is the logical OR of any of the following values:
  723. //!
  724. //! - SSI_DMA_RX - disable DMA for receive
  725. //! - SSI_DMA_TX - disable DMA for transmit
  726. //!
  727. //! \return None.
  728. //
  729. //*****************************************************************************
  730. void
  731. SSIDMADisable(uint32_t ui32Base, uint32_t ui32DMAFlags)
  732. {
  733. //
  734. // Check the arguments.
  735. //
  736. ASSERT(_SSIBaseValid(ui32Base));
  737. //
  738. // Clear the requested bits in the SSI DMA control register.
  739. //
  740. HWREG(ui32Base + SSI_O_DMACTL) &= ~ui32DMAFlags;
  741. }
  742. //*****************************************************************************
  743. //
  744. //! Determines whether the SSI transmitter is busy or not.
  745. //!
  746. //! \param ui32Base is the base address of the SSI module.
  747. //!
  748. //! This function allows the caller to determine whether all transmitted bytes
  749. //! have cleared the transmitter hardware. If \b false is returned, then the
  750. //! transmit FIFO is empty and all bits of the last transmitted word have left
  751. //! the hardware shift register.
  752. //!
  753. //! \return Returns \b true if the SSI is transmitting or \b false if all
  754. //! transmissions are complete.
  755. //
  756. //*****************************************************************************
  757. bool
  758. SSIBusy(uint32_t ui32Base)
  759. {
  760. //
  761. // Check the arguments.
  762. //
  763. ASSERT(_SSIBaseValid(ui32Base));
  764. //
  765. // Determine if the SSI is busy.
  766. //
  767. return((HWREG(ui32Base + SSI_O_SR) & SSI_SR_BSY) ? true : false);
  768. }
  769. //*****************************************************************************
  770. //
  771. //! Sets the data clock source for the specified SSI peripheral.
  772. //!
  773. //! \param ui32Base is the base address of the SSI module.
  774. //! \param ui32Source is the baud clock source for the SSI.
  775. //!
  776. //! This function allows the baud clock source for the SSI to be selected.
  777. //! The possible clock source are the system clock (\b SSI_CLOCK_SYSTEM) or
  778. //! the precision internal oscillator (\b SSI_CLOCK_PIOSC).
  779. //!
  780. //! Changing the baud clock source changes the data rate generated by the
  781. //! SSI. Therefore, the data rate should be reconfigured after any change to
  782. //! the SSI clock source.
  783. //!
  784. //! \note The ability to specify the SSI baud clock source varies with the
  785. //! Tiva part and SSI in use. Please consult the data sheet for the part
  786. //! in use to determine whether this support is available.
  787. //!
  788. //! \return None.
  789. //
  790. //*****************************************************************************
  791. void
  792. SSIClockSourceSet(uint32_t ui32Base, uint32_t ui32Source)
  793. {
  794. //
  795. // Check the arguments.
  796. //
  797. ASSERT(_SSIBaseValid(ui32Base));
  798. ASSERT((ui32Source == SSI_CLOCK_SYSTEM) ||
  799. (ui32Source == SSI_CLOCK_PIOSC));
  800. //
  801. // Set the SSI clock source.
  802. //
  803. HWREG(ui32Base + SSI_O_CC) = ui32Source;
  804. }
  805. //*****************************************************************************
  806. //
  807. //! Gets the data clock source for the specified SSI peripheral.
  808. //!
  809. //! \param ui32Base is the base address of the SSI module.
  810. //!
  811. //! This function returns the data clock source for the specified SSI.
  812. //!
  813. //! \note The ability to specify the SSI data clock source varies with the
  814. //! Tiva part and SSI in use. Please consult the data sheet for the part
  815. //! in use to determine whether this support is available.
  816. //!
  817. //! \return Returns the current clock source, which is either
  818. //! \b SSI_CLOCK_SYSTEM or \b SSI_CLOCK_PIOSC.
  819. //
  820. //*****************************************************************************
  821. uint32_t
  822. SSIClockSourceGet(uint32_t ui32Base)
  823. {
  824. //
  825. // Check the arguments.
  826. //
  827. ASSERT(_SSIBaseValid(ui32Base));
  828. //
  829. // Return the SSI clock source.
  830. //
  831. return(HWREG(ui32Base + SSI_O_CC));
  832. }
  833. //*****************************************************************************
  834. //
  835. //! Selects the advanced mode of operation for the SSI module.
  836. //!
  837. //! \param ui32Base is the base address of the SSI module.
  838. //! \param ui32Mode is the mode of operation to use.
  839. //!
  840. //! This function selects the mode of operation for the SSI module, which is
  841. //! needed when using the advanced operation modes (Bi- or Quad-SPI). One of
  842. //! the following modes can be selected:
  843. //!
  844. //! - \b SSI_ADV_MODE_LEGACY - Disables the advanced modes of operation,
  845. //! resulting in legacy, or backwards-compatible, operation. When this mode
  846. //! is selected, it is not valid to switch to Bi- or Quad-SPI operation.
  847. //! This mode is the default.
  848. //! - \b SSI_ADV_MODE_WRITE - The advanced mode of operation where data is only
  849. //! written to the slave; any data clocked in via the \b SSIRx pin is thrown
  850. //! away (instead of being placed into the SSI Rx FIFO).
  851. //! - \b SSI_ADV_MODE_READ_WRITE - The advanced mode of operation where data is
  852. //! written to and read from the slave; this mode is the same as
  853. //! \b SSI_ADV_MODE_LEGACY but allows transitions to Bi- or Quad-SPI
  854. //! operation.
  855. //! - \b SSI_ADV_MODE_BI_READ - The advanced mode of operation where data is
  856. //! read from the slave in Bi-SPI mode, with two bits of data read on every
  857. //! SSI clock.
  858. //! - \b SSI_ADV_MODE_BI_WRITE - The advanced mode of operation where data is
  859. //! written to the slave in Bi-SPI mode, with two bits of data written on
  860. //! every SSI clock.
  861. //! - \b SSI_ADV_MODE_QUAD_READ - The advanced mode of operation where data is
  862. //! read from the slave in Quad-SPI mode, with four bits of data read on
  863. //! every SSI clock.
  864. //! - \b SSI_ADV_MODE_QUAD_WRITE - The advanced mode of operation where data is
  865. //! written to the slave in Quad-SPI mode, with four bits of data written on
  866. //! every SSI clock.
  867. //!
  868. //! The following mode transitions are valid (other transitions produce
  869. //! undefined results):
  870. //!
  871. //! \verbatim
  872. //! +----------+-------------------------------------------------------------+
  873. //! |FROM | TO |
  874. //! | |Legacy|Write|Read Write|Bi Read|Bi Write|Quad Read|Quad Write|
  875. //! +----------+------+-----+----------+-------+--------+---------+----------+
  876. //! |Legacy | yes | yes | yes | | | | |
  877. //! |Write | yes | yes | yes | yes | yes | yes | yes |
  878. //! |Read/Write| yes | yes | yes | yes | yes | yes | yes |
  879. //! |Bi Read | | yes | yes | yes | yes | | |
  880. //! |Bi write | | yes | yes | yes | yes | | |
  881. //! |Quad read | | yes | yes | | | yes | yes |
  882. //! |Quad write| | yes | yes | | | yes | yes |
  883. //! +----------+------+-----+----------+-------+--------+---------+----------+
  884. //! \endverbatim
  885. //!
  886. //! When using an advanced mode of operation, the SSI module must have been
  887. //! configured for eight data bits and the \b SSI_FRF_MOTO_MODE_0 protocol.
  888. //! The advanced mode operation that is selected applies only to data newly
  889. //! written into the FIFO; the data that is already present in the FIFO is
  890. //! handled using the advanced mode of operation in effect when that data was
  891. //! written.
  892. //!
  893. //! Switching into and out of legacy mode should only occur when the FIFO is
  894. //! empty.
  895. //!
  896. //! \note The availability of the advanced mode of SSI operation varies with
  897. //! the Tiva part and SSI in use. Please consult the data sheet for the
  898. //! part in use to determine whether this support is available.
  899. //!
  900. //! \return None.
  901. //
  902. //*****************************************************************************
  903. void
  904. SSIAdvModeSet(uint32_t ui32Base, uint32_t ui32Mode)
  905. {
  906. //
  907. // Check the arguments.
  908. //
  909. ASSERT(_SSIBaseValid(ui32Base));
  910. ASSERT((ui32Mode == SSI_ADV_MODE_LEGACY) ||
  911. (ui32Mode == SSI_ADV_MODE_WRITE) ||
  912. (ui32Mode == SSI_ADV_MODE_READ_WRITE) ||
  913. (ui32Mode == SSI_ADV_MODE_BI_READ) ||
  914. (ui32Mode == SSI_ADV_MODE_BI_WRITE) ||
  915. (ui32Mode == SSI_ADV_MODE_QUAD_READ) ||
  916. (ui32Mode == SSI_ADV_MODE_QUAD_WRITE));
  917. //
  918. // Set the SSI mode of operation.
  919. //
  920. HWREG(ui32Base + SSI_O_CR1) =
  921. ((HWREG(ui32Base + SSI_O_CR1) & ~(SSI_CR1_DIR | SSI_CR1_MODE_M)) |
  922. ui32Mode);
  923. }
  924. //*****************************************************************************
  925. //
  926. //! Puts a data element into the SSI transmit FIFO as the end of a frame.
  927. //!
  928. //! \param ui32Base specifies the SSI module base address.
  929. //! \param ui32Data is the data to be transmitted over the SSI interface.
  930. //!
  931. //! This function places the supplied data into the transmit FIFO of the
  932. //! specified SSI module, marking it as the end of a frame. If there is no
  933. //! space available in the transmit FIFO, this function waits until there is
  934. //! space available before returning. After this byte is transmitted by the
  935. //! SSI module, the FSS signal de-asserts for at least one SSI clock.
  936. //!
  937. //! \note The upper 24 bits of \e ui32Data are discarded by the hardware.
  938. //!
  939. //! \note The availability of the advanced mode of SSI operation varies with
  940. //! the Tiva part and SSI in use. Please consult the data sheet for the
  941. //! part in use to determine whether this support is available.
  942. //!
  943. //! \return None.
  944. //
  945. //*****************************************************************************
  946. void
  947. SSIAdvDataPutFrameEnd(uint32_t ui32Base, uint32_t ui32Data)
  948. {
  949. //
  950. // Check the arguments.
  951. //
  952. ASSERT(_SSIBaseValid(ui32Base));
  953. ASSERT((ui32Data & 0xff) == 0);
  954. //
  955. // Wait until there is space.
  956. //
  957. while(!(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF))
  958. {
  959. }
  960. //
  961. // Write the data to the SSI.
  962. //
  963. HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_EOM;
  964. HWREG(ui32Base + SSI_O_DR) = ui32Data;
  965. }
  966. //*****************************************************************************
  967. //
  968. //! Puts a data element into the SSI transmit FIFO as the end of a frame.
  969. //!
  970. //! \param ui32Base specifies the SSI module base address.
  971. //! \param ui32Data is the data to be transmitted over the SSI interface.
  972. //!
  973. //! This function places the supplied data into the transmit FIFO of the
  974. //! specified SSI module, marking it as the end of a frame. After this byte is
  975. //! transmitted by the SSI module, the FSS signal de-asserts for at least one
  976. //! SSI clock. If there is no space in the FIFO, then this function returns a
  977. //! zero.
  978. //!
  979. //! \note The upper 24 bits of \e ui32Data are discarded by the hardware.
  980. //!
  981. //! \note The availability of the advanced mode of SSI operation varies with
  982. //! the Tiva part and SSI in use. Please consult the data sheet for the
  983. //! part in use to determine whether this support is available.
  984. //!
  985. //! \return Returns the number of elements written to the SSI transmit FIFO.
  986. //
  987. //*****************************************************************************
  988. int32_t
  989. SSIAdvDataPutFrameEndNonBlocking(uint32_t ui32Base, uint32_t ui32Data)
  990. {
  991. //
  992. // Check the arguments.
  993. //
  994. ASSERT(_SSIBaseValid(ui32Base));
  995. ASSERT((ui32Data & 0xff) == 0);
  996. //
  997. // Check for space to write.
  998. //
  999. if(HWREG(ui32Base + SSI_O_SR) & SSI_SR_TNF)
  1000. {
  1001. HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_EOM;
  1002. HWREG(ui32Base + SSI_O_DR) = ui32Data;
  1003. return(1);
  1004. }
  1005. else
  1006. {
  1007. return(0);
  1008. }
  1009. }
  1010. //*****************************************************************************
  1011. //
  1012. //! Configures the SSI advanced mode to hold the SSIFss signal during the full
  1013. //! transfer.
  1014. //!
  1015. //! \param ui32Base is the base address of the SSI module.
  1016. //!
  1017. //! This function configures the SSI module to de-assert the SSIFss signal
  1018. //! during the entire data transfer when using one of the advanced modes
  1019. //! (instead of briefly de-asserting it after every byte). When using this
  1020. //! mode, SSIFss can be directly controlled via SSIAdvDataPutFrameEnd() and
  1021. //! SSIAdvDataPutFrameEndNonBlocking().
  1022. //!
  1023. //! \note The availability of the advanced mode of SSI operation varies with
  1024. //! the Tiva part and SSI in use. Please consult the data sheet for the
  1025. //! part in use to determine whether this support is available.
  1026. //!
  1027. //! \return None.
  1028. //
  1029. //*****************************************************************************
  1030. void
  1031. SSIAdvFrameHoldEnable(uint32_t ui32Base)
  1032. {
  1033. //
  1034. // Check the arguments.
  1035. //
  1036. ASSERT(_SSIBaseValid(ui32Base));
  1037. //
  1038. // Set the hold frame bit.
  1039. //
  1040. HWREG(ui32Base + SSI_O_CR1) |= SSI_CR1_FSSHLDFRM;
  1041. }
  1042. //*****************************************************************************
  1043. //
  1044. //! Configures the SSI advanced mode to de-assert the SSIFss signal after every
  1045. //! byte transfer.
  1046. //!
  1047. //! \param ui32Base is the base address of the SSI module.
  1048. //!
  1049. //! This function configures the SSI module to de-assert the SSIFss signal
  1050. //! for one SSI clock cycle after every byte is transferred using one of the
  1051. //! advanced modes (instead of leaving it asserted for the entire transfer).
  1052. //! This mode is the default operation.
  1053. //!
  1054. //! \note The availability of the advanced mode of SSI operation varies with
  1055. //! the Tiva part and SSI in use. Please consult the data sheet for the
  1056. //! part in use to determine whether this support is available.
  1057. //!
  1058. //! \return None.
  1059. //
  1060. //*****************************************************************************
  1061. void
  1062. SSIAdvFrameHoldDisable(uint32_t ui32Base)
  1063. {
  1064. //
  1065. // Check the arguments.
  1066. //
  1067. ASSERT(_SSIBaseValid(ui32Base));
  1068. //
  1069. // Clear the hold frame bit.
  1070. //
  1071. HWREG(ui32Base + SSI_O_CR1) &= ~(SSI_CR1_FSSHLDFRM);
  1072. }
  1073. //*****************************************************************************
  1074. //
  1075. // Close the Doxygen group.
  1076. //! @}
  1077. //
  1078. //*****************************************************************************