am_hal_ios.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  1. //*****************************************************************************
  2. //
  3. // am_hal_ios.c
  4. //! @file
  5. //!
  6. //! @brief Functions for interfacing with the IO Slave module
  7. //!
  8. //! @addtogroup ios2 IO Slave (SPI/I2C)
  9. //! @ingroup apollo2hal
  10. //! @{
  11. //
  12. //*****************************************************************************
  13. //*****************************************************************************
  14. //
  15. // Copyright (c) 2017, Ambiq Micro
  16. // All rights reserved.
  17. //
  18. // Redistribution and use in source and binary forms, with or without
  19. // modification, are permitted provided that the following conditions are met:
  20. //
  21. // 1. Redistributions of source code must retain the above copyright notice,
  22. // this list of conditions and the following disclaimer.
  23. //
  24. // 2. Redistributions in binary form must reproduce the above copyright
  25. // notice, this list of conditions and the following disclaimer in the
  26. // documentation and/or other materials provided with the distribution.
  27. //
  28. // 3. Neither the name of the copyright holder nor the names of its
  29. // contributors may be used to endorse or promote products derived from this
  30. // software without specific prior written permission.
  31. //
  32. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  36. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  37. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  38. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  39. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  40. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42. // POSSIBILITY OF SUCH DAMAGE.
  43. //
  44. // This is part of revision 1.2.9 of the AmbiqSuite Development Package.
  45. //
  46. //*****************************************************************************
  47. #include <stdint.h>
  48. #include <stdbool.h>
  49. #include "am_mcu_apollo.h"
  50. //*****************************************************************************
  51. //
  52. // SRAM Buffer structure
  53. //
  54. //*****************************************************************************
  55. typedef struct
  56. {
  57. uint8_t *pui8Data;
  58. volatile uint32_t ui32WriteIndex;
  59. volatile uint32_t ui32ReadIndex;
  60. volatile uint32_t ui32Length;
  61. uint32_t ui32Capacity;
  62. }
  63. am_hal_ios_buffer_t;
  64. am_hal_ios_buffer_t g_sSRAMBuffer;
  65. //*****************************************************************************
  66. //
  67. // Forward declarations of static funcitons.
  68. //
  69. //*****************************************************************************
  70. static void am_hal_ios_buffer_init(am_hal_ios_buffer_t *psBuffer,
  71. void *pvArray, uint32_t ui32Bytes);
  72. static void fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes);
  73. //*****************************************************************************
  74. //
  75. // Function-like macros.
  76. //
  77. //*****************************************************************************
  78. #define am_hal_ios_buffer_empty(psBuffer) \
  79. ((psBuffer)->ui32Length == 0)
  80. #define am_hal_ios_buffer_full(psBuffer) \
  81. ((psBuffer)->ui32Length == (psBuffer)->ui32Capacity)
  82. #define am_hal_ios_buffer_data_left(psBuffer) \
  83. ((psBuffer)->ui32Length)
  84. //*****************************************************************************
  85. //
  86. // Global Variables
  87. //
  88. //*****************************************************************************
  89. volatile uint8_t * const am_hal_ios_pui8LRAM = (uint8_t *)REG_IOSLAVE_BASEADDR;
  90. uint8_t *g_pui8FIFOBase = (uint8_t *) REG_IOSLAVE_BASEADDR;
  91. uint8_t *g_pui8FIFOEnd = (uint8_t *) REG_IOSLAVE_BASEADDR;
  92. uint8_t *g_pui8FIFOPtr = (uint8_t *) REG_IOSLAVE_BASEADDR;
  93. uint8_t g_ui32HwFifoSize = 0;
  94. uint32_t g_ui32FifoBaseOffset = 0;
  95. //*****************************************************************************
  96. //
  97. //! @brief Enable the IOS in the power control block.
  98. //!
  99. //! This function enables the IOS module in the power control block.
  100. //!
  101. //! @return None.
  102. //
  103. //*****************************************************************************
  104. void
  105. am_hal_ios_pwrctrl_enable(void)
  106. {
  107. am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_IOS);
  108. }
  109. //*****************************************************************************
  110. //
  111. //! @brief Disable the IOS in the power control block.
  112. //!
  113. //! This function disables the IOS module in the power control block.
  114. //!
  115. //! @return None.
  116. //
  117. //*****************************************************************************
  118. void
  119. am_hal_ios_pwrctrl_disable(void)
  120. {
  121. am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_IOS);
  122. }
  123. //*****************************************************************************
  124. //
  125. //! @brief Enables the IOS module
  126. //!
  127. //! This function enables the IOSLAVE module using the IFCEN bitfield in the
  128. //! IOSLAVE_CFG register.
  129. //!
  130. //! @return None.
  131. //
  132. //*****************************************************************************
  133. void
  134. am_hal_ios_enable(uint32_t ui32Module)
  135. {
  136. AM_REGn(IOSLAVE, ui32Module, CFG) |= AM_REG_IOSLAVE_CFG_IFCEN(1);
  137. }
  138. //*****************************************************************************
  139. //
  140. //! @brief Disables the IOSLAVE module.
  141. //!
  142. //! This function disables the IOSLAVE module using the IFCEN bitfield in the
  143. //! IOSLAVE_CFG register.
  144. //!
  145. //! @return None.
  146. //
  147. //*****************************************************************************
  148. void
  149. am_hal_ios_disable(uint32_t ui32Module)
  150. {
  151. AM_REGn(IOSLAVE, ui32Module, CFG) &= ~(AM_REG_IOSLAVE_CFG_IFCEN(1));
  152. }
  153. //*****************************************************************************
  154. //
  155. //! @brief Configure the IOS module.
  156. //!
  157. //! This function reads the an \e am_hal_ios_config_t structure and uses it to
  158. //! set up the IO Slave module. Please see the information on the configuration
  159. //! structure for more information on the parameters that may be set by this
  160. //! function.
  161. //!
  162. //! @return None.
  163. //
  164. //*****************************************************************************
  165. void
  166. am_hal_ios_config(am_hal_ios_config_t *psConfig)
  167. {
  168. uint32_t ui32LRAMConfig;
  169. am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_IOS);
  170. //
  171. // Record the FIFO parameters for later use.
  172. //
  173. g_pui8FIFOBase = (uint8_t *)(REG_IOSLAVE_BASEADDR + psConfig->ui32FIFOBase);
  174. g_pui8FIFOEnd = (uint8_t *)(REG_IOSLAVE_BASEADDR + psConfig->ui32RAMBase);
  175. g_ui32HwFifoSize = g_pui8FIFOEnd - g_pui8FIFOBase;
  176. g_ui32FifoBaseOffset = psConfig->ui32FIFOBase;
  177. //
  178. // Caluclate the value for the IO Slave FIFO configuration register.
  179. //
  180. ui32LRAMConfig = AM_REG_IOSLAVE_FIFOCFG_ROBASE(psConfig->ui32ROBase >> 3);
  181. ui32LRAMConfig |= AM_REG_IOSLAVE_FIFOCFG_FIFOBASE(psConfig->ui32FIFOBase >> 3);
  182. ui32LRAMConfig |= AM_REG_IOSLAVE_FIFOCFG_FIFOMAX(psConfig->ui32RAMBase >> 3);
  183. //
  184. // Just in case, disable the IOS
  185. //
  186. am_hal_ios_disable(0);
  187. //
  188. // Write the configuration register with the user's selected interface
  189. // characteristics.
  190. //
  191. AM_REG(IOSLAVE, CFG) = psConfig->ui32InterfaceSelect;
  192. //
  193. // Write the FIFO configuration register to set the memory map for the LRAM.
  194. //
  195. AM_REG(IOSLAVE, FIFOCFG) = ui32LRAMConfig;
  196. //
  197. // Enable the IOS. The following configuration options can't be set while
  198. // the IOS is disabled.
  199. //
  200. am_hal_ios_enable(0);
  201. //
  202. // Initialize the FIFO pointer to the beginning of the FIFO section.
  203. //
  204. am_hal_ios_fifo_ptr_set(psConfig->ui32FIFOBase);
  205. //
  206. // Write the FIFO threshold register.
  207. //
  208. AM_REG(IOSLAVE, FIFOTHR) = psConfig->ui32FIFOThreshold;
  209. }
  210. //*****************************************************************************
  211. //
  212. //! @brief Set bits in the HOST side IOINTCTL register.
  213. //!
  214. //! This function may be used to set an interrupt bit to the host.
  215. //!
  216. //! @return None.
  217. //
  218. //*****************************************************************************
  219. void
  220. am_hal_ios_host_int_set(uint32_t ui32Interrupt)
  221. {
  222. //
  223. // Set a bit that will cause an interrupt to the host.
  224. //
  225. AM_REG(IOSLAVE, IOINTCTL) = AM_REG_IOSLAVE_IOINTCTL_IOINTSET(ui32Interrupt);
  226. }
  227. //*****************************************************************************
  228. //
  229. //! @brief Clear bits in the HOST side IOINTCTL register.
  230. //!
  231. //! This function may be used to clear an interrupt bit to the host.
  232. //!
  233. //! @return None.
  234. //
  235. //*****************************************************************************
  236. void
  237. am_hal_ios_host_int_clear(uint32_t ui32Interrupt)
  238. {
  239. //
  240. // Clear bits that will cause an interrupt to the host.
  241. //
  242. AM_REG(IOSLAVE, IOINTCTL) = AM_REG_IOSLAVE_IOINTCTL_IOINTCLR(ui32Interrupt);
  243. }
  244. //*****************************************************************************
  245. //
  246. //! @brief Get the bits in the HOST side IOINTCTL register.
  247. //!
  248. //! This function may be used to read the host side interrupt bits.
  249. //!
  250. //! @return None.
  251. //
  252. //*****************************************************************************
  253. uint32_t
  254. am_hal_ios_host_int_get(void)
  255. {
  256. //
  257. // return the value of the bits that will cause an interrupt to the host.
  258. //
  259. return AM_BFR(IOSLAVE, IOINTCTL, IOINT);
  260. }
  261. //*****************************************************************************
  262. //
  263. //! @brief Get the enable bits in the HOST side IOINTCTL register.
  264. //!
  265. //! This function may be used to read the host side interrupt bits.
  266. //!
  267. //! @return None.
  268. //
  269. //*****************************************************************************
  270. uint32_t
  271. am_hal_ios_host_int_enable_get(void)
  272. {
  273. //
  274. // return the value of the bits that will cause an interrupt to the host.
  275. //
  276. return AM_BFR(IOSLAVE, IOINTCTL, IOINTEN);
  277. }
  278. //*****************************************************************************
  279. //
  280. //! @brief Enable an IOS Access Interrupt.
  281. //!
  282. //! This function may be used to enable an interrupt to the NVIC.
  283. //!
  284. //! @return None.
  285. //
  286. //*****************************************************************************
  287. void
  288. am_hal_ios_access_int_enable(uint32_t ui32Interrupt)
  289. {
  290. //
  291. // OR the desired interrupt into the enable register.
  292. //
  293. AM_REG(IOSLAVE, REGACCINTEN) |= ui32Interrupt;
  294. }
  295. //*****************************************************************************
  296. //
  297. //! @brief Return all enabled IOS Access Interrupts.
  298. //!
  299. //! This function may be used to return all enabled IOS Access interrupts.
  300. //!
  301. //! @return the enabled interrrupts.
  302. //
  303. //*****************************************************************************
  304. uint32_t
  305. am_hal_ios_access_int_enable_get(void)
  306. {
  307. //
  308. // Return the enabled interrupts.
  309. //
  310. return AM_REG(IOSLAVE, REGACCINTEN);
  311. }
  312. //*****************************************************************************
  313. //
  314. //! @brief Disable an IOS Access Interrupt.
  315. //!
  316. //! This function may be used to disable an interrupt to the NVIC.
  317. //!
  318. //! @return None.
  319. //
  320. //*****************************************************************************
  321. void
  322. am_hal_ios_access_int_disable(uint32_t ui32Interrupt)
  323. {
  324. //
  325. // Clear the desired bit from the interrupt enable register.
  326. //
  327. AM_REG(IOSLAVE, REGACCINTEN) &= ~(ui32Interrupt);
  328. }
  329. //*****************************************************************************
  330. //
  331. //! @brief Clear an IOS Access Interrupt.
  332. //!
  333. //! This function may be used to clear an interrupt to the NVIC.
  334. //!
  335. //! @return None.
  336. //
  337. //*****************************************************************************
  338. void
  339. am_hal_ios_access_int_clear(uint32_t ui32Interrupt)
  340. {
  341. //
  342. // Use the interrupt clear register to deactivate the chosen interrupt.
  343. //
  344. AM_REG(IOSLAVE, REGACCINTCLR) = ui32Interrupt;
  345. }
  346. //*****************************************************************************
  347. //
  348. //! @brief Set an IOS Access Interrupt.
  349. //!
  350. //! This function may be used to set an interrupt to the NVIC.
  351. //!
  352. //! @return None.
  353. //
  354. //*****************************************************************************
  355. void
  356. am_hal_ios_access_int_set(uint32_t ui32Interrupt)
  357. {
  358. //
  359. // Use the interrupt set register to activate the chosen interrupt.
  360. //
  361. AM_REG(IOSLAVE, REGACCINTSET) = ui32Interrupt;
  362. }
  363. //*****************************************************************************
  364. //
  365. //! @brief Check the status of an IOS Access Interrupt.
  366. //!
  367. //! @param bEnabledOnly - return only the enabled interrupt status.
  368. //!
  369. //! This function may be used to return the enabled interrupt status.
  370. //!
  371. //! @return the enabled interrupt status.
  372. //
  373. //*****************************************************************************
  374. uint32_t
  375. am_hal_ios_access_int_status_get(bool bEnabledOnly)
  376. {
  377. if ( bEnabledOnly )
  378. {
  379. uint32_t u32RetVal = AM_REG(IOSLAVE, REGACCINTSTAT);
  380. return u32RetVal & AM_REG(IOSLAVE, REGACCINTEN);
  381. }
  382. else
  383. {
  384. return AM_REG(IOSLAVE, REGACCINTSTAT);
  385. }
  386. }
  387. //*****************************************************************************
  388. //
  389. //! @brief Enable an IOS Interrupt.
  390. //!
  391. //! @param ui32Interrupt - desired interrupts.
  392. //!
  393. //! This function may be used to enable an interrupt to the NVIC.
  394. //!
  395. //! @return None.
  396. //
  397. //*****************************************************************************
  398. void
  399. am_hal_ios_int_enable(uint32_t ui32Interrupt)
  400. {
  401. //
  402. // OR the desired interrupt into the enable register.
  403. //
  404. AM_REG(IOSLAVE, INTEN) |= ui32Interrupt;
  405. }
  406. //*****************************************************************************
  407. //
  408. //! @brief Return all enabled IOS Interrupts.
  409. //!
  410. //! This function may be used to return all enabled IOS interrupts.
  411. //!
  412. //! @return the enabled interrrupts.
  413. //
  414. //*****************************************************************************
  415. uint32_t
  416. am_hal_ios_int_enable_get(void)
  417. {
  418. //
  419. // Return the enabled interrupts.
  420. //
  421. return AM_REG(IOSLAVE, INTEN);
  422. }
  423. //*****************************************************************************
  424. //
  425. //! @brief Disable an IOS Interrupt.
  426. //!
  427. //! @param ui32Interrupt - desired interrupts.
  428. //!
  429. //! This function may be used to disable an interrupt to the NVIC.
  430. //!
  431. //! @return None.
  432. //
  433. //*****************************************************************************
  434. void
  435. am_hal_ios_int_disable(uint32_t ui32Interrupt)
  436. {
  437. //
  438. // Clear the desired bit from the interrupt enable register.
  439. //
  440. AM_REG(IOSLAVE, INTEN) &= ~(ui32Interrupt);
  441. }
  442. //*****************************************************************************
  443. //
  444. //! @brief Clear an IOS Interrupt.
  445. //!
  446. //! @param ui32Interrupt - desired interrupts.
  447. //!
  448. //! This function may be used to clear an interrupt to the NVIC.
  449. //!
  450. //! @return None.
  451. //
  452. //*****************************************************************************
  453. void
  454. am_hal_ios_int_clear(uint32_t ui32Interrupt)
  455. {
  456. //
  457. // Use the interrupt clear register to deactivate the chosen interrupt.
  458. //
  459. AM_REG(IOSLAVE, INTCLR) = ui32Interrupt;
  460. }
  461. //*****************************************************************************
  462. //
  463. //! @brief Set an IOS Interrupt.
  464. //!
  465. //! @param ui32Interrupt - desired interrupts.
  466. //!
  467. //! This function may be used to set an interrupt to the NVIC.
  468. //!
  469. //! @return None.
  470. //
  471. //*****************************************************************************
  472. void
  473. am_hal_ios_int_set(uint32_t ui32Interrupt)
  474. {
  475. //
  476. // Use the interrupt clear register to deactivate the chosen interrupt.
  477. //
  478. AM_REG(IOSLAVE, INTSET) = ui32Interrupt;
  479. }
  480. //*****************************************************************************
  481. //
  482. //! @brief Write to the LRAM.
  483. //!
  484. //! @param ui32Offset - offset into the LRAM to write.
  485. //! @param ui8Value - value to be written.
  486. //!
  487. //! This function writes ui8Value to offset ui32Offset inside the LRAM.
  488. //!
  489. //! @return None.
  490. //
  491. //*****************************************************************************
  492. void
  493. am_hal_ios_lram_write(uint32_t ui32Offset, uint8_t ui8Value)
  494. {
  495. //
  496. // Write the LRAM.
  497. //
  498. am_hal_ios_pui8LRAM[ui32Offset] = ui8Value;
  499. }
  500. //*****************************************************************************
  501. //
  502. //! @brief Read from the LRAM.
  503. //!
  504. //! @param ui32Offset - offset into the LRAM to read.
  505. //!
  506. //! This function read from offset ui32Offset inside the LRAM.
  507. //!
  508. //! @return the value at ui32Offset.
  509. //
  510. //*****************************************************************************
  511. uint8_t
  512. am_hal_ios_lram_read(uint32_t ui32Offset)
  513. {
  514. //
  515. // Read the LRAM.
  516. //
  517. return am_hal_ios_pui8LRAM[ui32Offset];
  518. }
  519. //*****************************************************************************
  520. //
  521. //! @brief Check the status of an IOS Interrupt.
  522. //!
  523. //! @param bEnabledOnly - return only the enabled interrupt status.
  524. //!
  525. //! This function may be used to return the enabled interrupt status.
  526. //!
  527. //! @return the enabled interrupt status.
  528. //
  529. //*****************************************************************************
  530. uint32_t
  531. am_hal_ios_int_status_get(bool bEnabledOnly)
  532. {
  533. if ( bEnabledOnly )
  534. {
  535. uint32_t u32RetVal = AM_REG(IOSLAVE, INTSTAT);
  536. return u32RetVal & AM_REG(IOSLAVE, INTEN);
  537. }
  538. else
  539. {
  540. return AM_REG(IOSLAVE, INTSTAT);
  541. }
  542. }
  543. //*****************************************************************************
  544. //
  545. //! @brief Check the amount of space used in the FIFO
  546. //!
  547. //! This function returns the available data in the overall FIFO yet to be
  548. //! read by the host. This takes into account the SRAM buffer and hardware FIFO
  549. //!
  550. //! @return Bytes used in the Overall FIFO.
  551. //
  552. //*****************************************************************************
  553. uint32_t
  554. am_hal_ios_fifo_space_used(void)
  555. {
  556. uint32_t ui32Val;
  557. uint32_t ui32Primask;
  558. //
  559. // Start a critical section for thread safety.
  560. //
  561. ui32Primask = am_hal_interrupt_master_disable();
  562. ui32Val = g_sSRAMBuffer.ui32Length;
  563. ui32Val += AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ);
  564. //
  565. // End the critical section
  566. //
  567. am_hal_interrupt_master_set(ui32Primask);
  568. return ui32Val;
  569. }
  570. //*****************************************************************************
  571. //
  572. //! @brief Check the amount of space left in the FIFO
  573. //!
  574. //! This function returns the available space in the overall FIFO to accept
  575. //! new data. This takes into account the SRAM buffer and hardware FIFO
  576. //!
  577. //! @return Bytes left in the Overall FIFO.
  578. //
  579. //*****************************************************************************
  580. uint32_t
  581. am_hal_ios_fifo_space_left(void)
  582. {
  583. uint32_t ui32Val;
  584. uint32_t ui32Primask;
  585. //
  586. // Start a critical section for thread safety.
  587. //
  588. ui32Primask = am_hal_interrupt_master_disable();
  589. //
  590. // We waste one byte in HW FIFO
  591. //
  592. ui32Val = g_sSRAMBuffer.ui32Capacity + g_ui32HwFifoSize - 1;
  593. ui32Val -= g_sSRAMBuffer.ui32Length;
  594. ui32Val -= AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ);
  595. //
  596. // End the critical section
  597. //
  598. am_hal_interrupt_master_set(ui32Primask);
  599. return ui32Val;
  600. }
  601. //*****************************************************************************
  602. //
  603. //! @brief Check the amount of space left in the hardware FIFO
  604. //!
  605. //! This function reads the IOSLAVE FIFOPTR register and determines the amount
  606. //! of space left in the IOS LRAM FIFO.
  607. //!
  608. //! @return Bytes left in the IOS FIFO.
  609. //
  610. //*****************************************************************************
  611. static uint32_t
  612. fifo_space_left(void)
  613. {
  614. //
  615. // We waste one byte in HW FIFO
  616. //
  617. return ((uint32_t)g_ui32HwFifoSize- AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ) - 1);
  618. }
  619. //*****************************************************************************
  620. //
  621. // Helper function for managing IOS FIFO writes.
  622. //
  623. //*****************************************************************************
  624. static void
  625. fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes)
  626. {
  627. uint8_t *pFifoPtr = g_pui8FIFOPtr;
  628. uint8_t *pFifoBase = g_pui8FIFOBase;
  629. uint8_t *pFifoEnd = g_pui8FIFOEnd;
  630. while ( ui32NumBytes )
  631. {
  632. //
  633. // Write the data to the FIFO
  634. //
  635. *pFifoPtr++ = *pui8Data++;
  636. ui32NumBytes--;
  637. //
  638. // Make sure to wrap the FIFO pointer if necessary.
  639. //
  640. if ( pFifoPtr == pFifoEnd )
  641. {
  642. pFifoPtr = pFifoBase;
  643. }
  644. }
  645. g_pui8FIFOPtr = pFifoPtr;
  646. }
  647. //
  648. // Assembly code below assumes 8bit FIFOSIZ field aligned at a byte boundary
  649. //
  650. #if (((AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M >> AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S) != 0xFF) \
  651. || (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S & 0x3))
  652. #error "FIFOSIZ not 8bit value aligned at byte offset"
  653. #endif
  654. //
  655. // Byte offset of FIFOSIZ field in FIFOPTR register
  656. //
  657. #define BYTEOFFSET_FIFOSIZE (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S >> 3)
  658. //*****************************************************************************
  659. //
  660. // Helper function in assembly for implementing the ReSync
  661. //
  662. //*****************************************************************************
  663. #if defined(__GNUC_STDC_INLINE__)
  664. #if (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S != 8)
  665. #error "AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S not 8"
  666. #endif
  667. __attribute__((naked))
  668. static void
  669. internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr)
  670. {
  671. __asm
  672. (
  673. " push {r3,r4}\n\t" // Save r3, r4 - used by this function
  674. "__internal_resync_fifoSize_loop:\n\t"
  675. " ldr r4, [r2]\n\t" // Load FIFOPTR register in r4
  676. " ubfx r3, r4, #8, #8\n\t" // Extract hwFifoSize to r3
  677. " uxtb r4, r4\n\t" // Extract rdOffset in r4
  678. " subs r4, r0, r4\n\t" // fifoSize in r4 = wrOffset - rdOffset
  679. " it cc\n\t" // if (wrOffset < rdOffset)
  680. " addcc r4, r4, r1\n\t" // fifoSize = maxFifoSize - (rdOffset - wrOffset)
  681. " cmp r3, r4\n\t" // (hwFifoSize != fifoSize)
  682. " beq __internal_resync_fifosize_done\n\t"
  683. " strb r4, [r2, #1]\n\t" // Overwrite FIFOSIZ value with fifoSize
  684. " b __internal_resync_fifoSize_loop\n\t" // Repeat the check
  685. "__internal_resync_fifosize_done:\n\t"
  686. " pop {r3,r4}\n\t" // Restore registers
  687. " bx lr\n\t"
  688. );
  689. }
  690. #elif defined(__ARMCC_VERSION)
  691. __asm static void
  692. internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr)
  693. {
  694. push {r3, r4} // Save r3, r4 - used by this function
  695. internal_resync_fifoSize_loop
  696. ldr r4, [r2] // Load FIFOPTR register in r4
  697. ubfx r3, r4, #AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S, #8 // Extract hwFifoSize to r3
  698. uxtb r4, r4 // Extract rdOffset in r4
  699. subs r4, r0, r4 // fifoSize in r4 = wrOffset - rdOffset
  700. it cc // if (wrOffset < rdOffset),
  701. addcc r4, r4, r1 // fifoSize = maxFifoSize - (rdOffset - wrOffset)
  702. cmp r3, r4 // (hwFifoSize != fifoSize)
  703. beq internal_resync_fifosize_done
  704. strb r4, [r2, #1] // Overwrite FIFOSIZ value with fifoSize
  705. b internal_resync_fifoSize_loop // Repeat the check
  706. internal_resync_fifosize_done
  707. pop {r3, r4} // Restore registers
  708. bx lr
  709. }
  710. #elif defined(__IAR_SYSTEMS_ICC__)
  711. #if (AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S != 8)
  712. #error "AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S not 8"
  713. #endif
  714. __stackless static void
  715. internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr)
  716. {
  717. __asm volatile (
  718. " push {r3,r4}\n" // Save r3, r4 - used by this function
  719. "__internal_resync_fifoSize_loop:\n"
  720. " ldr r4, [r2]\n" // Load FIFOPTR register in r4
  721. " ubfx r3, r4, #8, #8\n" // Extract hwFifoSize to r3
  722. " uxtb r4, r4\n" // Extract rdOffset in r4
  723. " subs r4, r0, r4\n" // fifoSize in r4 = wrOffset - rdOffset
  724. " it cc\n"
  725. " addcc r4, r4, r1\n" // fifoSize = maxFifoSize - (rdOffset - wrOffset)
  726. " cmp r3, r4\n" // (fifoSize != hwFifoSize)
  727. " beq __internal_resync_fifosize_done\n"
  728. " strb r4, [r2, #1]\n" // Overwrite FIFOSIZ value with fifoSize
  729. " b __internal_resync_fifoSize_loop\n" // Repeat the check
  730. "__internal_resync_fifosize_done:\n"
  731. " pop {r3,r4}\n" // Restore registers
  732. " bx lr\n"
  733. );
  734. }
  735. #else
  736. static void
  737. internal_resync_fifoSize(uint32_t wrOffset, uint32_t maxFifoSize, uint32_t hwFifoPtrRegAddr)
  738. {
  739. uint32_t fifoSize;
  740. uint32_t hwFifoPtrReg;
  741. uint32_t rdOffset;
  742. uint32_t hwFifoSize;
  743. hwFifoPtrReg = AM_REGVAL(hwFifoPtrRegAddr);
  744. rdOffset = ((hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_S);
  745. hwFifoSize = (hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S;
  746. // By wasting one byte in hardware FIFO, we're guaranteed that fifoSize does not need special handling for FULL FIFO case
  747. fifoSize = ((wrOffset >= rdOffset) ? (wrOffset - rdOffset) : (maxFifoSize - (rdOffset - wrOffset)));
  748. while ( fifoSize != hwFifoSize )
  749. {
  750. // Overwite correct FIFOSIZ
  751. // Need to do a Byte Write to make sure the FIFOPTR is not overwritten
  752. *((uint8_t *)(hwFifoPtrRegAddr + BYTEOFFSET_FIFOSIZE)) = fifoSize;
  753. // Read back the register and check for consistency
  754. hwFifoPtrReg = AM_REGVAL(hwFifoPtrRegAddr);
  755. rdOffset = ((hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOPTR_S);
  756. hwFifoSize = (hwFifoPtrReg & AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_M) >> AM_REG_IOSLAVE_FIFOPTR_FIFOSIZ_S;
  757. // By wasting one byte in hardware FIFO, we're guaranteed that fifoSize does not need special handling for FULL FIFO case
  758. fifoSize = ((wrOffset >= rdOffset) ? (wrOffset - rdOffset) : (hwFifoSize - (rdOffset - wrOffset)));
  759. }
  760. }
  761. #endif
  762. //
  763. // Address of the FIFOPTR register
  764. //
  765. #define AM_REG_IOS_FIFOPTR (REG_IOSLAVE_BASEADDR + AM_REG_IOSLAVE_FIFOPTR_O)
  766. // When the FIFO is being replenished by the SW, at the same time as host is
  767. // reading from it, there is a possible race condition, where the hardware decrement
  768. // of FIFOSIZ as a result of read gets overwritten by hardware increment due to
  769. // write.
  770. // This function re-sync's the FIFOSIZ to ensure such errors do not accumulate
  771. void
  772. resync_fifoSize(void)
  773. {
  774. uint32_t ui32Primask;
  775. uint32_t wrOffset = (uint32_t)g_pui8FIFOPtr - (uint32_t)am_hal_ios_pui8LRAM;
  776. //
  777. // Start a critical section for thread safety.
  778. //
  779. ui32Primask = am_hal_interrupt_master_disable();
  780. internal_resync_fifoSize(wrOffset, g_ui32HwFifoSize, AM_REG_IOS_FIFOPTR);
  781. // Clear interrupts for IOS which could be spuriously triggered
  782. AM_REG(IOSLAVE, REGACCINTCLR) = (AM_HAL_IOS_INT_FSIZE | AM_HAL_IOS_INT_FOVFL | AM_HAL_IOS_INT_FUNDFL);
  783. //
  784. // End the critical section
  785. //
  786. am_hal_interrupt_master_set(ui32Primask);
  787. return;
  788. }
  789. //*****************************************************************************
  790. //
  791. //! @brief Transfer any available data from the IOS SRAM buffer to the FIFO.
  792. //!
  793. //! This function is meant to be called from an interrupt handler for the
  794. //! ioslave module. It checks the IOS FIFO interrupt status for a threshold
  795. //! event, and transfers data from an SRAM buffer into the IOS FIFO.
  796. //!
  797. //! @param ui32Status should be set to the ios interrupt status at the time of
  798. //! ISR entry.
  799. //!
  800. //! @return None.
  801. //
  802. //*****************************************************************************
  803. void
  804. am_hal_ios_fifo_service(uint32_t ui32Status)
  805. {
  806. uint32_t thresh;
  807. uint32_t freeSpace, usedSpace, chunk1, chunk2, ui32WriteIndex;
  808. //
  809. // Check for FIFO size interrupts.
  810. //
  811. if ( ui32Status & AM_HAL_IOS_INT_FSIZE )
  812. {
  813. thresh = AM_BFR(IOSLAVE, FIFOTHR, FIFOTHR);
  814. //
  815. // While the FIFO is at or below threshold Add more data
  816. // If Fifo level is above threshold, we're guaranteed an FSIZ interrupt
  817. //
  818. while ( g_sSRAMBuffer.ui32Length &&
  819. ((usedSpace = AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ)) <= thresh) )
  820. {
  821. //
  822. // So, we do have some data in SRAM which needs to be moved to FIFO.
  823. // A chunk of data is a continguous set of bytes in SRAM that can be
  824. // written to FIFO. Determine the chunks of data from SRAM that can
  825. // be written. Up to two chunks possible
  826. //
  827. ui32WriteIndex = g_sSRAMBuffer.ui32WriteIndex;
  828. chunk1 = ((ui32WriteIndex > (uint32_t)g_sSRAMBuffer.ui32ReadIndex) ? \
  829. (ui32WriteIndex - (uint32_t)g_sSRAMBuffer.ui32ReadIndex) : \
  830. (g_sSRAMBuffer.ui32Capacity - (uint32_t)g_sSRAMBuffer.ui32ReadIndex));
  831. chunk2 = g_sSRAMBuffer.ui32Length - chunk1;
  832. // We waste one byte in HW FIFO
  833. freeSpace = g_ui32HwFifoSize - usedSpace - 1;
  834. // Write data in chunks
  835. // Determine the chunks of data from SRAM that can be written
  836. if ( chunk1 > freeSpace )
  837. {
  838. fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), freeSpace);
  839. //
  840. // Advance the read index, wrapping if needed.
  841. //
  842. g_sSRAMBuffer.ui32ReadIndex += freeSpace;
  843. // No need to check for wrap as we wrote less than chunk1
  844. //
  845. // Adjust the length value to reflect the change.
  846. //
  847. g_sSRAMBuffer.ui32Length -= freeSpace;
  848. }
  849. else
  850. {
  851. fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), chunk1);
  852. //
  853. // Update the read index - wrapping as needed
  854. //
  855. g_sSRAMBuffer.ui32ReadIndex += chunk1;
  856. g_sSRAMBuffer.ui32ReadIndex %= g_sSRAMBuffer.ui32Capacity;
  857. //
  858. // Adjust the length value to reflect the change.
  859. //
  860. g_sSRAMBuffer.ui32Length -= chunk1;
  861. freeSpace -= chunk1;
  862. if ( freeSpace && chunk2 )
  863. {
  864. if ( chunk2 > freeSpace )
  865. {
  866. fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), freeSpace);
  867. //
  868. // Advance the read index, wrapping if needed.
  869. //
  870. g_sSRAMBuffer.ui32ReadIndex += freeSpace;
  871. // No need to check for wrap in chunk2
  872. //
  873. // Adjust the length value to reflect the change.
  874. //
  875. g_sSRAMBuffer.ui32Length -= freeSpace;
  876. }
  877. else
  878. {
  879. fifo_write((uint8_t *)(g_sSRAMBuffer.pui8Data + g_sSRAMBuffer.ui32ReadIndex), chunk2);
  880. //
  881. // Advance the read index, wrapping if needed.
  882. //
  883. g_sSRAMBuffer.ui32ReadIndex += chunk2;
  884. // No need to check for wrap in chunk2
  885. //
  886. // Adjust the length value to reflect the change.
  887. //
  888. g_sSRAMBuffer.ui32Length -= chunk2;
  889. }
  890. }
  891. }
  892. resync_fifoSize();
  893. //
  894. // Need to retake the FIFO space, after Threshold interrupt has been reenabled
  895. // Clear any spurious FSIZE interrupt that might have got raised
  896. //
  897. AM_BFW(IOSLAVE, INTCLR, FSIZE, 1);
  898. }
  899. }
  900. }
  901. //*****************************************************************************
  902. //
  903. //! @brief Writes the specified number of bytes to the IOS fifo.
  904. //!
  905. //! @param pui8Data is a pointer to the data to be written to the fifo.
  906. //! @param ui32NumBytes is the number of bytes to send.
  907. //!
  908. //! This function will write data from the caller-provided array to the IOS
  909. //! LRAM FIFO. If there is no space in the LRAM FIFO, the data will be copied
  910. //! to a temporary SRAM buffer instead.
  911. //!
  912. //! The maximum message size for the IO Slave is 1023 bytes.
  913. //!
  914. //! @note In order for SRAM copy operations in the function to work correctly,
  915. //! the \e am_hal_ios_buffer_service() function must be called in the ISR for
  916. //! the ioslave module.
  917. //!
  918. //! @return Number of bytes written (could be less than ui32NumBytes, if not enough space)
  919. //
  920. //*****************************************************************************
  921. uint32_t
  922. am_hal_ios_fifo_write(uint8_t *pui8Data, uint32_t ui32NumBytes)
  923. {
  924. uint32_t ui32FIFOSpace;
  925. uint32_t ui32SRAMSpace;
  926. uint32_t ui32SRAMLength;
  927. uint32_t ui32Primask;
  928. uint32_t totalBytes = ui32NumBytes;
  929. //
  930. // This operation will only work properly if an SRAM buffer has been
  931. // allocated. Make sure that am_hal_ios_fifo_buffer_init() has been called,
  932. // and the buffer pointer looks valid.
  933. //
  934. am_hal_debug_assert(g_sSRAMBuffer.pui8Data != 0);
  935. if ( ui32NumBytes == 0 )
  936. {
  937. return 0;
  938. }
  939. //
  940. // Start a critical section for thread safety.
  941. //
  942. ui32Primask = am_hal_interrupt_master_disable();
  943. ui32SRAMLength = g_sSRAMBuffer.ui32Length;
  944. //
  945. // End the critical section
  946. //
  947. am_hal_interrupt_master_set(ui32Primask);
  948. //
  949. // If the SRAM buffer is empty, we should just write directly to the FIFO.
  950. //
  951. if ( ui32SRAMLength == 0 )
  952. {
  953. ui32FIFOSpace = fifo_space_left();
  954. //
  955. // If the whole message fits, send it now.
  956. //
  957. if ( ui32NumBytes <= ui32FIFOSpace )
  958. {
  959. fifo_write(pui8Data, ui32NumBytes);
  960. ui32NumBytes = 0;
  961. }
  962. else
  963. {
  964. fifo_write(pui8Data, ui32FIFOSpace);
  965. ui32NumBytes -= ui32FIFOSpace;
  966. pui8Data += ui32FIFOSpace;
  967. };
  968. resync_fifoSize();
  969. }
  970. //
  971. // If there's still data, write it to the SRAM buffer.
  972. //
  973. if ( ui32NumBytes )
  974. {
  975. uint32_t idx, writeIdx, capacity, fifoSize;
  976. ui32SRAMSpace = g_sSRAMBuffer.ui32Capacity - ui32SRAMLength;
  977. writeIdx = g_sSRAMBuffer.ui32WriteIndex;
  978. capacity = g_sSRAMBuffer.ui32Capacity;
  979. //
  980. // Make sure that the data will fit inside the SRAM buffer.
  981. //
  982. if ( ui32SRAMSpace > ui32NumBytes )
  983. {
  984. ui32SRAMSpace = ui32NumBytes;
  985. }
  986. //
  987. // If the data will fit, write it to the SRAM buffer.
  988. //
  989. for ( idx = 0; idx < ui32SRAMSpace; idx++ )
  990. {
  991. g_sSRAMBuffer.pui8Data[(idx + writeIdx) % capacity] = pui8Data[idx];
  992. }
  993. ui32NumBytes -= idx;
  994. //
  995. // Start a critical section for thread safety before updating length & wrIdx.
  996. //
  997. ui32Primask = am_hal_interrupt_master_disable();
  998. //
  999. // Advance the write index, making sure to wrap if necessary.
  1000. //
  1001. g_sSRAMBuffer.ui32WriteIndex = (idx + writeIdx) % capacity;
  1002. //
  1003. // Update the length value appropriately.
  1004. //
  1005. g_sSRAMBuffer.ui32Length += idx;
  1006. //
  1007. // End the critical section
  1008. //
  1009. am_hal_interrupt_master_set(ui32Primask);
  1010. // It is possible that there is a race condition that the FIFO level has
  1011. // gone below the threshold by the time we set the wrIdx above, and hence
  1012. // we may never get the threshold interrupt to serve the SRAM data we
  1013. // just wrote
  1014. // If that is the case, explicitly generate the FSIZE interrupt from here
  1015. fifoSize = AM_BFR(IOSLAVE, FIFOPTR, FIFOSIZ);
  1016. if ( fifoSize <= AM_BFR(IOSLAVE, FIFOTHR, FIFOTHR) )
  1017. {
  1018. AM_BFW(IOSLAVE, INTSET, FSIZE, 1);
  1019. }
  1020. }
  1021. return (totalBytes - ui32NumBytes);
  1022. }
  1023. //*****************************************************************************
  1024. //
  1025. //! @brief Writes the specified number of bytes to the IOS fifo simply.
  1026. //!
  1027. //! @param pui8Data is a pointer to the data to be written to the fifo.
  1028. //! @param ui32NumBytes is the number of bytes to send.
  1029. //!
  1030. //! This function will write data from the caller-provided array to the IOS
  1031. //! LRAM FIFO. This simple routine does not use SRAM buffering for large
  1032. //! messages.
  1033. //!
  1034. //! The maximum message size for the IO Slave is 128 bytes.
  1035. //!
  1036. //! @note Do note call the \e am_hal_ios_buffer_service() function in the ISR for
  1037. //! the ioslave module.
  1038. //!
  1039. //! @return
  1040. //
  1041. //*****************************************************************************
  1042. void
  1043. am_hal_ios_fifo_write_simple(uint8_t *pui8Data, uint32_t ui32NumBytes)
  1044. {
  1045. uint32_t ui32FIFOSpace;
  1046. //
  1047. // Check the FIFO and the SRAM buffer to see where we have space.
  1048. //
  1049. ui32FIFOSpace = fifo_space_left();
  1050. //
  1051. // If the whole message fits, send it now.
  1052. //
  1053. if ( ui32NumBytes <= ui32FIFOSpace )
  1054. {
  1055. fifo_write(pui8Data, ui32NumBytes);
  1056. }
  1057. else
  1058. {
  1059. //
  1060. // The message didn't fit. Try using am_hal_ios_fifo_write() instead.
  1061. //
  1062. am_hal_debug_assert_msg(0, "The requested IOS transfer didn't fit in"
  1063. "the LRAM FIFO. Try using am_hal_ios_fifo_write().");
  1064. }
  1065. }
  1066. //*****************************************************************************
  1067. //
  1068. //! @brief Sets the IOS FIFO pointer to the specified LRAM offset.
  1069. //!
  1070. //! @param ui32Offset is LRAM offset to set the FIFO pointer to.
  1071. //!
  1072. //! @return None.
  1073. //
  1074. //*****************************************************************************
  1075. void
  1076. am_hal_ios_fifo_ptr_set(uint32_t ui32Offset)
  1077. {
  1078. uint32_t ui32Primask;
  1079. //
  1080. // Start a critical section for thread safety.
  1081. //
  1082. ui32Primask = am_hal_interrupt_master_disable();
  1083. //
  1084. // Set the FIFO Update bit.
  1085. //
  1086. AM_REG(IOSLAVE, FUPD) = 0x1;
  1087. //
  1088. // Change the FIFO offset.
  1089. //
  1090. AM_REG(IOSLAVE, FIFOPTR) = ui32Offset;
  1091. //
  1092. // Clear the FIFO update bit.
  1093. //
  1094. AM_REG(IOSLAVE, FUPD) = 0x0;
  1095. //
  1096. // Set the global FIFO-pointer tracking variable.
  1097. //
  1098. g_pui8FIFOPtr = (uint8_t *) (REG_IOSLAVE_BASEADDR + ui32Offset);
  1099. //
  1100. // End the critical section.
  1101. //
  1102. am_hal_interrupt_master_set(ui32Primask);
  1103. }
  1104. //*****************************************************************************
  1105. //
  1106. // Initialize an SRAM buffer for use with the IO Slave.
  1107. //
  1108. //*****************************************************************************
  1109. static void
  1110. am_hal_ios_buffer_init(am_hal_ios_buffer_t *psBuffer, void *pvArray,
  1111. uint32_t ui32Bytes)
  1112. {
  1113. psBuffer->ui32WriteIndex = 0;
  1114. psBuffer->ui32ReadIndex = 0;
  1115. psBuffer->ui32Length = 0;
  1116. psBuffer->ui32Capacity = ui32Bytes;
  1117. psBuffer->pui8Data = (uint8_t *)pvArray;
  1118. }
  1119. //*****************************************************************************
  1120. //
  1121. //! @brief Poll for all host side read activity to complete.
  1122. //!
  1123. //! Poll for all host side read activity to complete. Use this before
  1124. //! calling am_hal_ios_fifo_write_simple().
  1125. //!
  1126. //! @return None.
  1127. //
  1128. //*****************************************************************************
  1129. void
  1130. am_hal_ios_read_poll_complete(void)
  1131. {
  1132. while ( AM_REG(IOSLAVE, FUPD) & AM_REG_IOSLAVE_FUPD_IOREAD_M );
  1133. }
  1134. //*****************************************************************************
  1135. //
  1136. //! @brief Initializes an SRAM buffer for the IOS FIFO.
  1137. //!
  1138. //! @param pui8Buffer is the SRAM buffer that will be used for IOS fifo data.
  1139. //! @param ui32BufferSize is the size of the SRAM buffer.
  1140. //!
  1141. //! This function provides the IOS HAL functions with working memory for
  1142. //! managing outgoing IOS FIFO transactions. It needs to be called at least
  1143. //! once before am_hal_ios_fifo_write() may be used.
  1144. //!
  1145. //! The recommended buffer size for the IOS FIFO is 1024 bytes.
  1146. //!
  1147. //! @return None.
  1148. //
  1149. //*****************************************************************************
  1150. void
  1151. am_hal_ios_fifo_buffer_init(uint8_t *pui8Buffer, uint32_t ui32NumBytes)
  1152. {
  1153. //
  1154. // Initialize the global SRAM buffer
  1155. // Total size, which is SRAM Buffer plus the hardware FIFO needs to be
  1156. // limited to 1023
  1157. //
  1158. if ( ui32NumBytes > (1023 - g_ui32HwFifoSize + 1) )
  1159. {
  1160. ui32NumBytes = (1023 - g_ui32HwFifoSize + 1);
  1161. }
  1162. am_hal_ios_buffer_init(&g_sSRAMBuffer, pui8Buffer, ui32NumBytes);
  1163. //
  1164. // Clear the FIFO State
  1165. //
  1166. AM_BFW(IOSLAVE, FIFOCTR, FIFOCTR, 0x0);
  1167. AM_BFW(IOSLAVE, FIFOPTR, FIFOSIZ, 0x0);
  1168. am_hal_ios_fifo_ptr_set(g_ui32FifoBaseOffset);
  1169. }
  1170. //*****************************************************************************
  1171. //
  1172. //! @brief Update the FIFOCTR to inform host of available data to read.
  1173. //!
  1174. //! This function allows the application to indicate to HAL when it is safe to
  1175. //! update the FIFOCTR.
  1176. //!
  1177. //! Application needs to implement some sort of
  1178. //! synchronization with the host to make sure host is not reading FIFOCTR while
  1179. //! it is being updated by the MCU, since the FIFOCTR read over
  1180. //! IO is not an atomic operation.
  1181. //!
  1182. //!
  1183. //! @return None.
  1184. //
  1185. //*****************************************************************************
  1186. void
  1187. am_hal_ios_update_fifoctr(void)
  1188. {
  1189. uint32_t ui32Val;
  1190. // Determine the available data
  1191. ui32Val = am_hal_ios_fifo_space_used();
  1192. // Update FIFOCTR
  1193. AM_BFW(IOSLAVE, FIFOCTR, FIFOCTR, ui32Val);
  1194. return;
  1195. }
  1196. //*****************************************************************************
  1197. //
  1198. // End the doxygen group
  1199. //! @}
  1200. //
  1201. //*****************************************************************************