1
0

ssi.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. //*****************************************************************************
  2. //
  3. // ssi.c - Driver for Synchronous Serial Interface.
  4. //
  5. // Copyright (c) 2005-2011 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
  22. //
  23. //*****************************************************************************
  24. //*****************************************************************************
  25. //
  26. //! \addtogroup ssi_api
  27. //! @{
  28. //
  29. //*****************************************************************************
  30. #include "inc/hw_ints.h"
  31. #include "inc/hw_memmap.h"
  32. #include "inc/hw_ssi.h"
  33. #include "inc/hw_types.h"
  34. #include "driverlib/debug.h"
  35. #include "driverlib/interrupt.h"
  36. #include "driverlib/ssi.h"
  37. //*****************************************************************************
  38. //
  39. // A mapping of timer base address to interupt number.
  40. //
  41. //*****************************************************************************
  42. static const unsigned long g_ppulSSIIntMap[][2] =
  43. {
  44. { SSI0_BASE, INT_SSI0 },
  45. { SSI1_BASE, INT_SSI1 },
  46. { SSI2_BASE, INT_SSI2 },
  47. { SSI3_BASE, INT_SSI3 },
  48. };
  49. //*****************************************************************************
  50. //
  51. //! \internal
  52. //! Checks an SSI base address.
  53. //!
  54. //! \param ulBase specifies the SSI module base address.
  55. //!
  56. //! This function determines if a SSI module base address is valid.
  57. //!
  58. //! \return Returns \b true if the base address is valid and \b false
  59. //! otherwise.
  60. //
  61. //*****************************************************************************
  62. #ifdef DEBUG
  63. static tBoolean
  64. SSIBaseValid(unsigned long ulBase)
  65. {
  66. return((ulBase == SSI0_BASE) || (ulBase == SSI1_BASE) ||
  67. (ulBase == SSI2_BASE) || (ulBase == SSI3_BASE));
  68. }
  69. #endif
  70. //*****************************************************************************
  71. //
  72. //! \internal
  73. //! Gets the SSI interrupt number.
  74. //!
  75. //! \param ulBase specifies the SSI module base address.
  76. //!
  77. //! Given a SSI base address, returns the corresponding interrupt number.
  78. //!
  79. //! \return Returns an SSI interrupt number, or -1 if \e ulBase is invalid.
  80. //
  81. //*****************************************************************************
  82. static long
  83. SSIIntNumberGet(unsigned long ulBase)
  84. {
  85. unsigned long ulIdx;
  86. //
  87. // Loop through the table that maps SSI base addresses to interrupt
  88. // numbers.
  89. //
  90. for(ulIdx = 0; ulIdx < (sizeof(g_ppulSSIIntMap) /
  91. sizeof(g_ppulSSIIntMap[0])); ulIdx++)
  92. {
  93. //
  94. // See if this base address matches.
  95. //
  96. if(g_ppulSSIIntMap[ulIdx][0] == ulBase)
  97. {
  98. //
  99. // Return the corresponding interrupt number.
  100. //
  101. return(g_ppulSSIIntMap[ulIdx][1]);
  102. }
  103. }
  104. //
  105. // The base address could not be found, so return an error.
  106. //
  107. return(-1);
  108. }
  109. //*****************************************************************************
  110. //
  111. //! Configures the synchronous serial interface.
  112. //!
  113. //! \param ulBase specifies the SSI module base address.
  114. //! \param ulSSIClk is the rate of the clock supplied to the SSI module.
  115. //! \param ulProtocol specifies the data transfer protocol.
  116. //! \param ulMode specifies the mode of operation.
  117. //! \param ulBitRate specifies the clock rate.
  118. //! \param ulDataWidth specifies number of bits transferred per frame.
  119. //!
  120. //! This function configures the synchronous serial interface. It sets
  121. //! the SSI protocol, mode of operation, bit rate, and data width.
  122. //!
  123. //! The \e ulProtocol parameter defines the data frame format. The
  124. //! \e ulProtocol parameter can be one of the following values:
  125. //! \b SSI_FRF_MOTO_MODE_0, \b SSI_FRF_MOTO_MODE_1, \b SSI_FRF_MOTO_MODE_2,
  126. //! \b SSI_FRF_MOTO_MODE_3, \b SSI_FRF_TI, or \b SSI_FRF_NMW. The Motorola
  127. //! frame formats encode the following polarity and phase configurations:
  128. //!
  129. //! <pre>
  130. //! Polarity Phase Mode
  131. //! 0 0 SSI_FRF_MOTO_MODE_0
  132. //! 0 1 SSI_FRF_MOTO_MODE_1
  133. //! 1 0 SSI_FRF_MOTO_MODE_2
  134. //! 1 1 SSI_FRF_MOTO_MODE_3
  135. //! </pre>
  136. //!
  137. //! The \e ulMode parameter defines the operating mode of the SSI module. The
  138. //! SSI module can operate as a master or slave; if it is a slave, the SSI can
  139. //! be configured to disable output on its serial output line. The \e ulMode
  140. //! parameter can be one of the following values: \b SSI_MODE_MASTER,
  141. //! \b SSI_MODE_SLAVE, or \b SSI_MODE_SLAVE_OD.
  142. //!
  143. //! The \e ulBitRate parameter defines the bit rate for the SSI. This bit rate
  144. //! must satisfy the following clock ratio criteria:
  145. //!
  146. //! - FSSI >= 2 * bit rate (master mode); this speed cannot exceed 25 MHz.
  147. //! - FSSI >= 12 * bit rate or 6 * bit rate (slave modes), depending on the
  148. //! capability of the specific microcontroller
  149. //!
  150. //! where FSSI is the frequency of the clock supplied to the SSI module.
  151. //!
  152. //! The \e ulDataWidth parameter defines the width of the data transfers and
  153. //! can be a value between 4 and 16, inclusive.
  154. //!
  155. //! The peripheral clock is the same as the processor clock. This value is
  156. //! returned by SysCtlClockGet(), or it can be explicitly hard coded if it is
  157. //! constant and known (to save the code/execution overhead of a call to
  158. //! SysCtlClockGet()).
  159. //!
  160. //! This function replaces the original SSIConfig() API and performs the same
  161. //! actions. A macro is provided in <tt>ssi.h</tt> to map the original API to
  162. //! this API.
  163. //!
  164. //! \return None.
  165. //
  166. //*****************************************************************************
  167. void
  168. SSIConfigSetExpClk(unsigned long ulBase, unsigned long ulSSIClk,
  169. unsigned long ulProtocol, unsigned long ulMode,
  170. unsigned long ulBitRate, unsigned long ulDataWidth)
  171. {
  172. unsigned long ulMaxBitRate;
  173. unsigned long ulRegVal;
  174. unsigned long ulPreDiv;
  175. unsigned long ulSCR;
  176. unsigned long ulSPH_SPO;
  177. //
  178. // Check the arguments.
  179. //
  180. ASSERT(SSIBaseValid(ulBase));
  181. ASSERT((ulProtocol == SSI_FRF_MOTO_MODE_0) ||
  182. (ulProtocol == SSI_FRF_MOTO_MODE_1) ||
  183. (ulProtocol == SSI_FRF_MOTO_MODE_2) ||
  184. (ulProtocol == SSI_FRF_MOTO_MODE_3) ||
  185. (ulProtocol == SSI_FRF_TI) ||
  186. (ulProtocol == SSI_FRF_NMW));
  187. ASSERT((ulMode == SSI_MODE_MASTER) ||
  188. (ulMode == SSI_MODE_SLAVE) ||
  189. (ulMode == SSI_MODE_SLAVE_OD));
  190. ASSERT(((ulMode == SSI_MODE_MASTER) && (ulBitRate <= (ulSSIClk / 2))) ||
  191. ((ulMode != SSI_MODE_MASTER) && (ulBitRate <= (ulSSIClk / 12))));
  192. ASSERT((ulSSIClk / ulBitRate) <= (254 * 256));
  193. ASSERT((ulDataWidth >= 4) && (ulDataWidth <= 16));
  194. //
  195. // Set the mode.
  196. //
  197. ulRegVal = (ulMode == SSI_MODE_SLAVE_OD) ? SSI_CR1_SOD : 0;
  198. ulRegVal |= (ulMode == SSI_MODE_MASTER) ? 0 : SSI_CR1_MS;
  199. HWREG(ulBase + SSI_O_CR1) = ulRegVal;
  200. //
  201. // Set the clock predivider.
  202. //
  203. ulMaxBitRate = ulSSIClk / ulBitRate;
  204. ulPreDiv = 0;
  205. do
  206. {
  207. ulPreDiv += 2;
  208. ulSCR = (ulMaxBitRate / ulPreDiv) - 1;
  209. }
  210. while(ulSCR > 255);
  211. HWREG(ulBase + SSI_O_CPSR) = ulPreDiv;
  212. //
  213. // Set protocol and clock rate.
  214. //
  215. ulSPH_SPO = (ulProtocol & 3) << 6;
  216. ulProtocol &= SSI_CR0_FRF_M;
  217. ulRegVal = (ulSCR << 8) | ulSPH_SPO | ulProtocol | (ulDataWidth - 1);
  218. HWREG(ulBase + SSI_O_CR0) = ulRegVal;
  219. }
  220. //*****************************************************************************
  221. //
  222. //! Enables the synchronous serial interface.
  223. //!
  224. //! \param ulBase specifies the SSI module base address.
  225. //!
  226. //! This function enables operation of the synchronous serial interface. The
  227. //! synchronous serial interface must be configured before it is enabled.
  228. //!
  229. //! \return None.
  230. //
  231. //*****************************************************************************
  232. void
  233. SSIEnable(unsigned long ulBase)
  234. {
  235. //
  236. // Check the arguments.
  237. //
  238. ASSERT(SSIBaseValid(ulBase));
  239. //
  240. // Read-modify-write the enable bit.
  241. //
  242. HWREG(ulBase + SSI_O_CR1) |= SSI_CR1_SSE;
  243. }
  244. //*****************************************************************************
  245. //
  246. //! Disables the synchronous serial interface.
  247. //!
  248. //! \param ulBase specifies the SSI module base address.
  249. //!
  250. //! This function disables operation of the synchronous serial interface.
  251. //!
  252. //! \return None.
  253. //
  254. //*****************************************************************************
  255. void
  256. SSIDisable(unsigned long ulBase)
  257. {
  258. //
  259. // Check the arguments.
  260. //
  261. ASSERT(SSIBaseValid(ulBase));
  262. //
  263. // Read-modify-write the enable bit.
  264. //
  265. HWREG(ulBase + SSI_O_CR1) &= ~(SSI_CR1_SSE);
  266. }
  267. //*****************************************************************************
  268. //
  269. //! Registers an interrupt handler for the synchronous serial interface.
  270. //!
  271. //! \param ulBase specifies the SSI module base address.
  272. //! \param pfnHandler is a pointer to the function to be called when the
  273. //! synchronous serial interface interrupt occurs.
  274. //!
  275. //! This function registers the handler to be called when an SSI interrupt
  276. //! occurs. This function enables the global interrupt in the interrupt
  277. //! controller; specific SSI interrupts must be enabled via SSIIntEnable(). If
  278. //! necessary, it is the interrupt handler's responsibility to clear the
  279. //! interrupt source via SSIIntClear().
  280. //!
  281. //! \sa IntRegister() for important information about registering interrupt
  282. //! handlers.
  283. //!
  284. //! \return None.
  285. //
  286. //*****************************************************************************
  287. void
  288. SSIIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
  289. {
  290. unsigned long ulInt;
  291. //
  292. // Check the arguments.
  293. //
  294. ASSERT(SSIBaseValid(ulBase));
  295. //
  296. // Determine the interrupt number based on the SSI port.
  297. //
  298. ulInt = SSIIntNumberGet(ulBase);
  299. //
  300. // Register the interrupt handler, returning an error if an error occurs.
  301. //
  302. IntRegister(ulInt, pfnHandler);
  303. //
  304. // Enable the synchronous serial interface interrupt.
  305. //
  306. IntEnable(ulInt);
  307. }
  308. //*****************************************************************************
  309. //
  310. //! Unregisters an interrupt handler for the synchronous serial interface.
  311. //!
  312. //! \param ulBase specifies the SSI module base address.
  313. //!
  314. //! This function clears the handler to be called when an SSI interrupt
  315. //! occurs. This function also masks off the interrupt in the interrupt
  316. //! controller so that the interrupt handler no longer is called.
  317. //!
  318. //! \sa IntRegister() for important information about registering interrupt
  319. //! handlers.
  320. //!
  321. //! \return None.
  322. //
  323. //*****************************************************************************
  324. void
  325. SSIIntUnregister(unsigned long ulBase)
  326. {
  327. unsigned long ulInt;
  328. //
  329. // Check the arguments.
  330. //
  331. ASSERT(SSIBaseValid(ulBase));
  332. //
  333. // Determine the interrupt number based on the SSI port.
  334. //
  335. ulInt = SSIIntNumberGet(ulBase);
  336. //
  337. // Disable the interrupt.
  338. //
  339. IntDisable(ulInt);
  340. //
  341. // Unregister the interrupt handler.
  342. //
  343. IntUnregister(ulInt);
  344. }
  345. //*****************************************************************************
  346. //
  347. //! Enables individual SSI interrupt sources.
  348. //!
  349. //! \param ulBase specifies the SSI module base address.
  350. //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
  351. //!
  352. //! This function enables the indicated SSI interrupt sources. Only the
  353. //! sources that are enabled can be reflected to the processor interrupt;
  354. //! disabled sources have no effect on the processor. The \e ulIntFlags
  355. //! parameter can be any of the \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, or
  356. //! \b SSI_RXOR values.
  357. //!
  358. //! \return None.
  359. //
  360. //*****************************************************************************
  361. void
  362. SSIIntEnable(unsigned long ulBase, unsigned long ulIntFlags)
  363. {
  364. //
  365. // Check the arguments.
  366. //
  367. ASSERT(SSIBaseValid(ulBase));
  368. //
  369. // Enable the specified interrupts.
  370. //
  371. HWREG(ulBase + SSI_O_IM) |= ulIntFlags;
  372. }
  373. //*****************************************************************************
  374. //
  375. //! Disables individual SSI interrupt sources.
  376. //!
  377. //! \param ulBase specifies the SSI module base address.
  378. //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
  379. //!
  380. //! This function disables the indicated SSI interrupt sources. The
  381. //! \e ulIntFlags parameter can be any of the \b SSI_TXFF, \b SSI_RXFF,
  382. //! \b SSI_RXTO, or \b SSI_RXOR values.
  383. //!
  384. //! \return None.
  385. //
  386. //*****************************************************************************
  387. void
  388. SSIIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
  389. {
  390. //
  391. // Check the arguments.
  392. //
  393. ASSERT(SSIBaseValid(ulBase));
  394. //
  395. // Disable the specified interrupts.
  396. //
  397. HWREG(ulBase + SSI_O_IM) &= ~(ulIntFlags);
  398. }
  399. //*****************************************************************************
  400. //
  401. //! Gets the current interrupt status.
  402. //!
  403. //! \param ulBase specifies the SSI module base address.
  404. //! \param bMasked is \b false if the raw interrupt status is required or
  405. //! \b true if the masked interrupt status is required.
  406. //!
  407. //! This function returns the interrupt status for the SSI module. Either the
  408. //! raw interrupt status or the status of interrupts that are allowed to
  409. //! reflect to the processor can be returned.
  410. //!
  411. //! \return The current interrupt status, enumerated as a bit field of
  412. //! \b SSI_TXFF, \b SSI_RXFF, \b SSI_RXTO, and \b SSI_RXOR.
  413. //
  414. //*****************************************************************************
  415. unsigned long
  416. SSIIntStatus(unsigned long ulBase, tBoolean bMasked)
  417. {
  418. //
  419. // Check the arguments.
  420. //
  421. ASSERT(SSIBaseValid(ulBase));
  422. //
  423. // Return either the interrupt status or the raw interrupt status as
  424. // requested.
  425. //
  426. if(bMasked)
  427. {
  428. return(HWREG(ulBase + SSI_O_MIS));
  429. }
  430. else
  431. {
  432. return(HWREG(ulBase + SSI_O_RIS));
  433. }
  434. }
  435. //*****************************************************************************
  436. //
  437. //! Clears SSI interrupt sources.
  438. //!
  439. //! \param ulBase specifies the SSI module base address.
  440. //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
  441. //!
  442. //! This function clears the specified SSI interrupt sources so that they no
  443. //! longer assert. This function must be called in the interrupt handler to
  444. //! keep the interrupts from being triggered again immediately upon exit. The
  445. //! \e ulIntFlags parameter can consist of either or both the \b SSI_RXTO and
  446. //! \b SSI_RXOR values.
  447. //!
  448. //! \note Because there is a write buffer in the Cortex-M processor, it may
  449. //! take several clock cycles before the interrupt source is actually cleared.
  450. //! Therefore, it is recommended that the interrupt source be cleared early in
  451. //! the interrupt handler (as opposed to the very last action) to avoid
  452. //! returning from the interrupt handler before the interrupt source is
  453. //! actually cleared. Failure to do so may result in the interrupt handler
  454. //! being immediately reentered (because the interrupt controller still sees
  455. //! the interrupt source asserted).
  456. //!
  457. //! \return None.
  458. //
  459. //*****************************************************************************
  460. void
  461. SSIIntClear(unsigned long ulBase, unsigned long ulIntFlags)
  462. {
  463. //
  464. // Check the arguments.
  465. //
  466. ASSERT(SSIBaseValid(ulBase));
  467. //
  468. // Clear the requested interrupt sources.
  469. //
  470. HWREG(ulBase + SSI_O_ICR) = ulIntFlags;
  471. }
  472. //*****************************************************************************
  473. //
  474. //! Puts a data element into the SSI transmit FIFO.
  475. //!
  476. //! \param ulBase specifies the SSI module base address.
  477. //! \param ulData is the data to be transmitted over the SSI interface.
  478. //!
  479. //! This function places the supplied data into the transmit FIFO of the
  480. //! specified SSI module.
  481. //!
  482. //! \note The upper 32 - N bits of the \e ulData are discarded by the hardware,
  483. //! where N is the data width as configured by SSIConfigSetExpClk(). For
  484. //! example, if the interface is configured for 8-bit data width, the upper 24
  485. //! bits of \e ulData are discarded.
  486. //!
  487. //! \return None.
  488. //
  489. //*****************************************************************************
  490. void
  491. SSIDataPut(unsigned long ulBase, unsigned long ulData)
  492. {
  493. //
  494. // Check the arguments.
  495. //
  496. ASSERT(SSIBaseValid(ulBase));
  497. ASSERT((ulData & (0xfffffffe << (HWREG(ulBase + SSI_O_CR0) &
  498. SSI_CR0_DSS_M))) == 0);
  499. //
  500. // Wait until there is space.
  501. //
  502. while(!(HWREG(ulBase + SSI_O_SR) & SSI_SR_TNF))
  503. {
  504. }
  505. //
  506. // Write the data to the SSI.
  507. //
  508. HWREG(ulBase + SSI_O_DR) = ulData;
  509. }
  510. //*****************************************************************************
  511. //
  512. //! Puts a data element into the SSI transmit FIFO.
  513. //!
  514. //! \param ulBase specifies the SSI module base address.
  515. //! \param ulData is the data to be transmitted over the SSI interface.
  516. //!
  517. //! This function places the supplied data into the transmit FIFO of the
  518. //! specified SSI module. If there is no space in the FIFO, then this function
  519. //! returns a zero.
  520. //!
  521. //! This function replaces the original SSIDataNonBlockingPut() API and
  522. //! performs the same actions. A macro is provided in <tt>ssi.h</tt> to map
  523. //! the original API to this API.
  524. //!
  525. //! \note The upper 32 - N bits of the \e ulData are discarded by the hardware,
  526. //! where N is the data width as configured by SSIConfigSetExpClk(). For
  527. //! example, if the interface is configured for 8-bit data width, the upper 24
  528. //! bits of \e ulData are discarded.
  529. //!
  530. //! \return Returns the number of elements written to the SSI transmit FIFO.
  531. //
  532. //*****************************************************************************
  533. long
  534. SSIDataPutNonBlocking(unsigned long ulBase, unsigned long ulData)
  535. {
  536. //
  537. // Check the arguments.
  538. //
  539. ASSERT(SSIBaseValid(ulBase));
  540. ASSERT((ulData & (0xfffffffe << (HWREG(ulBase + SSI_O_CR0) &
  541. SSI_CR0_DSS_M))) == 0);
  542. //
  543. // Check for space to write.
  544. //
  545. if(HWREG(ulBase + SSI_O_SR) & SSI_SR_TNF)
  546. {
  547. HWREG(ulBase + SSI_O_DR) = ulData;
  548. return(1);
  549. }
  550. else
  551. {
  552. return(0);
  553. }
  554. }
  555. //*****************************************************************************
  556. //
  557. //! Gets a data element from the SSI receive FIFO.
  558. //!
  559. //! \param ulBase specifies the SSI module base address.
  560. //! \param pulData is a pointer to a storage location for data that was
  561. //! received over the SSI interface.
  562. //!
  563. //! This function gets received data from the receive FIFO of the specified
  564. //! SSI module and places that data into the location specified by the
  565. //! \e pulData parameter.
  566. //!
  567. //! \note Only the lower N bits of the value written to \e pulData contain
  568. //! valid data, where N is the data width as configured by
  569. //! SSIConfigSetExpClk(). For example, if the interface is configured for
  570. //! 8-bit data width, only the lower 8 bits of the value written to \e pulData
  571. //! contain valid data.
  572. //!
  573. //! \return None.
  574. //
  575. //*****************************************************************************
  576. void
  577. SSIDataGet(unsigned long ulBase, unsigned long *pulData)
  578. {
  579. //
  580. // Check the arguments.
  581. //
  582. ASSERT(SSIBaseValid(ulBase));
  583. //
  584. // Wait until there is data to be read.
  585. //
  586. while(!(HWREG(ulBase + SSI_O_SR) & SSI_SR_RNE))
  587. {
  588. }
  589. //
  590. // Read data from SSI.
  591. //
  592. *pulData = HWREG(ulBase + SSI_O_DR);
  593. }
  594. //*****************************************************************************
  595. //
  596. //! Gets a data element from the SSI receive FIFO.
  597. //!
  598. //! \param ulBase specifies the SSI module base address.
  599. //! \param pulData is a pointer to a storage location for data that was
  600. //! received over the SSI interface.
  601. //!
  602. //! This function gets received data from the receive FIFO of the specified SSI
  603. //! module and places that data into the location specified by the \e ulData
  604. //! parameter. If there is no data in the FIFO, then this function returns a
  605. //! zero.
  606. //!
  607. //! This function replaces the original SSIDataNonBlockingGet() API and
  608. //! performs the same actions. A macro is provided in <tt>ssi.h</tt> to map
  609. //! the original API to this API.
  610. //!
  611. //! \note Only the lower N bits of the value written to \e pulData 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 \e pulData
  615. //! contain valid data.
  616. //!
  617. //! \return Returns the number of elements read from the SSI receive FIFO.
  618. //
  619. //*****************************************************************************
  620. long
  621. SSIDataGetNonBlocking(unsigned long ulBase, unsigned long *pulData)
  622. {
  623. //
  624. // Check the arguments.
  625. //
  626. ASSERT(SSIBaseValid(ulBase));
  627. //
  628. // Check for data to read.
  629. //
  630. if(HWREG(ulBase + SSI_O_SR) & SSI_SR_RNE)
  631. {
  632. *pulData = HWREG(ulBase + SSI_O_DR);
  633. return(1);
  634. }
  635. else
  636. {
  637. return(0);
  638. }
  639. }
  640. //*****************************************************************************
  641. //
  642. //! Enable SSI DMA operation.
  643. //!
  644. //! \param ulBase is the base address of the SSI port.
  645. //! \param ulDMAFlags is a bit mask of the DMA features to enable.
  646. //!
  647. //! This function enables the specified SSI DMA features. The SSI can be
  648. //! configured to use DMA for transmit and/or receive data transfers.
  649. //! The \e ulDMAFlags parameter is the logical OR of any of the following
  650. //! values:
  651. //!
  652. //! - SSI_DMA_RX - enable DMA for receive
  653. //! - SSI_DMA_TX - enable DMA for transmit
  654. //!
  655. //! \note The uDMA controller must also be set up before DMA can be used
  656. //! with the SSI.
  657. //!
  658. //! \return None.
  659. //
  660. //*****************************************************************************
  661. void
  662. SSIDMAEnable(unsigned long ulBase, unsigned long ulDMAFlags)
  663. {
  664. //
  665. // Check the arguments.
  666. //
  667. ASSERT(SSIBaseValid(ulBase));
  668. //
  669. // Set the requested bits in the SSI DMA control register.
  670. //
  671. HWREG(ulBase + SSI_O_DMACTL) |= ulDMAFlags;
  672. }
  673. //*****************************************************************************
  674. //
  675. //! Disable SSI DMA operation.
  676. //!
  677. //! \param ulBase is the base address of the SSI port.
  678. //! \param ulDMAFlags is a bit mask of the DMA features to disable.
  679. //!
  680. //! This function is used to disable SSI DMA features that were enabled
  681. //! by SSIDMAEnable(). The specified SSI DMA features are disabled. The
  682. //! \e ulDMAFlags parameter is the logical OR of any of the following values:
  683. //!
  684. //! - SSI_DMA_RX - disable DMA for receive
  685. //! - SSI_DMA_TX - disable DMA for transmit
  686. //!
  687. //! \return None.
  688. //
  689. //*****************************************************************************
  690. void
  691. SSIDMADisable(unsigned long ulBase, unsigned long ulDMAFlags)
  692. {
  693. //
  694. // Check the arguments.
  695. //
  696. ASSERT(SSIBaseValid(ulBase));
  697. //
  698. // Clear the requested bits in the SSI DMA control register.
  699. //
  700. HWREG(ulBase + SSI_O_DMACTL) &= ~ulDMAFlags;
  701. }
  702. //*****************************************************************************
  703. //
  704. //! Determines whether the SSI transmitter is busy or not.
  705. //!
  706. //! \param ulBase is the base address of the SSI port.
  707. //!
  708. //! This function allows the caller to determine whether all transmitted bytes
  709. //! have cleared the transmitter hardware. If \b false is returned, then the
  710. //! transmit FIFO is empty and all bits of the last transmitted word have left
  711. //! the hardware shift register.
  712. //!
  713. //! \return Returns \b true if the SSI is transmitting or \b false if all
  714. //! transmissions are complete.
  715. //
  716. //*****************************************************************************
  717. tBoolean
  718. SSIBusy(unsigned long ulBase)
  719. {
  720. //
  721. // Check the arguments.
  722. //
  723. ASSERT(SSIBaseValid(ulBase));
  724. //
  725. // Determine if the SSI is busy.
  726. //
  727. return((HWREG(ulBase + SSI_O_SR) & SSI_SR_BSY) ? true : false);
  728. }
  729. //*****************************************************************************
  730. //
  731. //! Sets the data clock source for the specified SSI peripheral.
  732. //!
  733. //! \param ulBase is the base address of the SSI port.
  734. //! \param ulSource is the baud clock source for the SSI.
  735. //!
  736. //! This function allows the baud clock source for the SSI to be selected.
  737. //! The possible clock source are the system clock (\b SSI_CLOCK_SYSTEM) or
  738. //! the precision internal oscillator (\b SSI_CLOCK_PIOSC).
  739. //!
  740. //! Changing the baud clock source changes the data rate generated by the
  741. //! SSI. Therefore, the data rate should be reconfigured after any change to
  742. //! the SSI clock source.
  743. //!
  744. //! \note The ability to specify the SSI baud clock source varies with the
  745. //! Stellaris part and SSI in use. Please consult the data sheet for the part
  746. //! you are using to determine whether this support is available.
  747. //!
  748. //! \return None.
  749. //
  750. //*****************************************************************************
  751. void
  752. SSIClockSourceSet(unsigned long ulBase, unsigned long ulSource)
  753. {
  754. //
  755. // Check the arguments.
  756. //
  757. ASSERT(SSIBaseValid(ulBase));
  758. ASSERT((ulSource == SSI_CLOCK_SYSTEM) || (ulSource == SSI_CLOCK_PIOSC));
  759. //
  760. // Set the SSI clock source.
  761. //
  762. HWREG(ulBase + SSI_O_CC) = ulSource;
  763. }
  764. //*****************************************************************************
  765. //
  766. //! Gets the data clock source for the specified SSI peripheral.
  767. //!
  768. //! \param ulBase is the base address of the SSI port.
  769. //!
  770. //! This function returns the data clock source for the specified SSI. The
  771. //! possible data clock source are the system clock (\b SSI_CLOCK_SYSTEM) or
  772. //! the precision internal oscillator (\b SSI_CLOCK_PIOSC).
  773. //!
  774. //! \note The ability to specify the SSI data clock source varies with the
  775. //! Stellaris part and SSI in use. Please consult the data sheet for the part
  776. //! you are using to determine whether this support is available.
  777. //!
  778. //! \return None.
  779. //
  780. //*****************************************************************************
  781. unsigned long
  782. SSIClockSourceGet(unsigned long ulBase)
  783. {
  784. //
  785. // Check the arguments.
  786. //
  787. ASSERT(SSIBaseValid(ulBase));
  788. //
  789. // Return the SSI clock source.
  790. //
  791. return(HWREG(ulBase + SSI_O_CC));
  792. }
  793. //*****************************************************************************
  794. //
  795. // Close the Doxygen group.
  796. //! @}
  797. //
  798. //*****************************************************************************