I2S_LPC18xx.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  1. /* --------------------------------------------------------------------------
  2. * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * $Date: 02. March 2016
  19. * $Revision: V1.4
  20. *
  21. * Driver: Driver_SAI0, Driver_SAI1
  22. * Configured: via RTE_Device.h configuration file
  23. * Project: SAI (I2S used for SAI) Driver for NXP LPC18xx
  24. * --------------------------------------------------------------------------
  25. * Use the following configuration settings in the middleware component
  26. * to connect to this driver.
  27. *
  28. * Configuration Setting Value SAI Interface
  29. * --------------------- ----- -------------
  30. * Connect to hardware via Driver_SAI# = 0 use SAI0 (I2S0)
  31. * Connect to hardware via Driver_SAI# = 1 use SAI1 (I2S1)
  32. * -------------------------------------------------------------------------- */
  33. /* History:
  34. * Version 1.4
  35. * - Driver update to work with GPDMA_LPC18xx ver.: 1.3
  36. * Version 1.3
  37. * - Corrected PowerControl function for conditional Power full (driver must be initialized)
  38. * Version 1.2
  39. * - PowerControl for Power OFF and Uninitialize functions made unconditional.
  40. * - Corrected status bit-field handling, to prevent race conditions.
  41. * Version 1.1
  42. * - Improved sampling frequency divider calculation
  43. * Version 1.0
  44. * - Initial release
  45. */
  46. #include "GPIO_LPC18xx.h"
  47. #include "I2S_LPC18xx.h"
  48. #include "RTE_Device.h"
  49. #include "RTE_Components.h"
  50. #include <math.h>
  51. #if ((!defined(RTE_I2S0)) || (!defined(RTE_I2S1)))
  52. #error "I2S missing in RTE_Device.h. Please update RTE_Device.h!"
  53. #endif
  54. #if ((defined(RTE_Drivers_SAI0) && !RTE_I2S0) && (defined(RTE_Drivers_SAI1) && !RTE_I2S1))
  55. #error "I2S0/1 not configured in RTE_Device.h!"
  56. #endif
  57. // Definitions
  58. // Frequency tolerance in percentage
  59. #ifndef I2S_FREQ_TOLERANCE
  60. #define I2S_FREQ_TOLERANCE (1.)
  61. #endif
  62. #define D2F_DOMAIN (255UL)
  63. #if (RTE_I2S0)
  64. // FIFO level can have value 1 to 7
  65. #ifndef I2S0_TX_FIFO_LEVEL
  66. #define I2S0_TX_FIFO_LEVEL ( 4U )
  67. #endif
  68. #ifndef I2S0_RX_FIFO_LEVEL
  69. #define I2S0_RX_FIFO_LEVEL ( 4U )
  70. #endif
  71. #if ((I2S0_TX_FIFO_LEVEL < 1U) || (I2S0_TX_FIFO_LEVEL > 7U))
  72. #error "Invalid FIFO Level value. FIFO Level can be 1 to 7"
  73. #endif
  74. #if ((I2S0_RX_FIFO_LEVEL < 1U) || (I2S0_RX_FIFO_LEVEL > 7U))
  75. #error "Invalid FIFO Level value. FIFO Level can be 1 to 7"
  76. #endif
  77. #endif
  78. #if (RTE_I2S1)
  79. // FIFO level can have value 1 to 7
  80. #ifndef I2S1_TX_FIFO_LEVEL
  81. #define I2S1_TX_FIFO_LEVEL ( 4U )
  82. #endif
  83. #ifndef I2S1_RX_FIFO_LEVEL
  84. #define I2S1_RX_FIFO_LEVEL ( 4U )
  85. #endif
  86. #if ((I2S1_TX_FIFO_LEVEL < 1U) || (I2S1_TX_FIFO_LEVEL > 7U))
  87. #error "Invalid FIFO Level value. FIFO Level can be 1 to 7"
  88. #endif
  89. #if ((I2S1_RX_FIFO_LEVEL < 1U) || (I2S1_RX_FIFO_LEVEL > 7U))
  90. #error "Invalid FIFO Level value. FIFO Level can be 1 to 7"
  91. #endif
  92. #endif
  93. #define ARM_SAI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,4) // driver version
  94. // Driver Version
  95. static const ARM_DRIVER_VERSION DriverVersion = {
  96. ARM_SAI_API_VERSION,
  97. ARM_SAI_DRV_VERSION
  98. };
  99. // I2S0
  100. #if (RTE_I2S0)
  101. static I2S_INFO I2S0_Info = {0};
  102. #if (RTE_I2S0_RX_SCK_PIN_EN == 1U)
  103. static PIN_ID I2S0_pin_rx_sck = { RTE_I2S0_RX_SCK_PORT, RTE_I2S0_RX_SCK_BIT, RTE_I2S0_RX_SCK_FUNC };
  104. #endif
  105. #if (RTE_I2S0_RX_WS_PIN_EN == 1U)
  106. static PIN_ID I2S0_pin_rx_ws = { RTE_I2S0_RX_WS_PORT, RTE_I2S0_RX_WS_BIT, RTE_I2S0_RX_WS_FUNC };
  107. #endif
  108. #if (RTE_I2S0_RX_SDA_PIN_EN == 1U)
  109. static PIN_ID I2S0_pin_rx_sda = { RTE_I2S0_RX_SDA_PORT, RTE_I2S0_RX_SDA_BIT, RTE_I2S0_RX_SDA_FUNC };
  110. #endif
  111. #if (RTE_I2S0_RX_MCLK_PIN_EN == 1U)
  112. static PIN_ID I2S0_pin_rx_mclk = { RTE_I2S0_RX_MCLK_PORT, RTE_I2S0_RX_MCLK_BIT, RTE_I2S0_RX_MCLK_FUNC };
  113. #endif
  114. #if (RTE_I2S0_TX_SCK_PIN_EN == 1U)
  115. static PIN_ID I2S0_pin_tx_sck = { RTE_I2S0_TX_SCK_PORT, RTE_I2S0_TX_SCK_BIT, RTE_I2S0_TX_SCK_FUNC };
  116. #endif
  117. #if (RTE_I2S0_TX_WS_PIN_EN == 1U)
  118. static PIN_ID I2S0_pin_tx_ws = { RTE_I2S0_TX_WS_PORT, RTE_I2S0_TX_WS_BIT, RTE_I2S0_TX_WS_FUNC };
  119. #endif
  120. #if (RTE_I2S0_TX_SDA_PIN_EN == 1U)
  121. static PIN_ID I2S0_pin_tx_sda = { RTE_I2S0_TX_SDA_PORT, RTE_I2S0_TX_SDA_BIT, RTE_I2S0_TX_SDA_FUNC };
  122. #endif
  123. #if (RTE_I2S0_TX_MCLK_PIN_EN == 1U)
  124. static PIN_ID I2S0_pin_tx_mclk = { RTE_I2S0_TX_MCLK_PORT, RTE_I2S0_TX_MCLK_BIT, RTE_I2S0_TX_MCLK_FUNC };
  125. #endif
  126. #if (RTE_I2S0_DMA_TX_EN == 1U)
  127. void I2S0_GPDMA_Tx_Event (uint32_t event);
  128. static I2S_DMA I2S0_DMA_Tx = {RTE_I2S0_DMA_TX_CH,
  129. RTE_I2S0_DMA_TX_PERI,
  130. RTE_I2S0_DMA_TX_PERI_SEL,
  131. I2S0_GPDMA_Tx_Event};
  132. #endif
  133. #if (RTE_I2S0_DMA_RX_EN == 1U)
  134. void I2S0_GPDMA_Rx_Event (uint32_t event);
  135. static I2S_DMA I2S0_DMA_Rx = {RTE_I2S0_DMA_RX_CH,
  136. RTE_I2S0_DMA_RX_PERI,
  137. RTE_I2S0_DMA_RX_PERI_SEL,
  138. I2S0_GPDMA_Rx_Event};
  139. #endif
  140. static const I2S_RESOURCES I2S0_Resources = {
  141. { // Capabilities
  142. 1, ///< supports asynchronous Transmit/Receive
  143. 1, ///< supports synchronous Transmit/Receive
  144. 0, ///< supports user defined Protocol
  145. 1, ///< supports I2S Protocol
  146. 0, ///< supports MSB/LSB justified Protocol
  147. 0, ///< supports PCM short/long frame Protocol
  148. 0, ///< supports AC'97 Protocol
  149. 1, ///< supports Mono mode
  150. 0, ///< supports Companding
  151. #if ((RTE_I2S0_TX_MCLK_PIN_EN == 1U) && (RTE_I2S0_RX_MCLK_PIN_EN == 1U))
  152. 1, ///< supports MCLK (Master Clock) pin
  153. #else
  154. 0, ///< supports MCLK (Master Clock) pin
  155. #endif
  156. 0, ///< supports Frame error event: \ref ARM_SAI_EVENT_FRAME_ERROR
  157. },
  158. LPC_I2S0,
  159. { // I2S0 RX Pin configuration
  160. #if (RTE_I2S0_RX_SCK_PIN_EN == 1U)
  161. &I2S0_pin_rx_sck,
  162. #else
  163. NULL,
  164. #endif
  165. #if (RTE_I2S0_RX_WS_PIN_EN == 1U)
  166. &I2S0_pin_rx_ws,
  167. #else
  168. NULL,
  169. #endif
  170. #if (RTE_I2S0_RX_SDA_PIN_EN == 1U)
  171. &I2S0_pin_rx_sda,
  172. #else
  173. NULL,
  174. #endif
  175. #if (RTE_I2S0_RX_MCLK_PIN_EN == 1U)
  176. &I2S0_pin_rx_mclk,
  177. #else
  178. NULL,
  179. #endif
  180. },
  181. { // I2S0 RX Pin configuration
  182. #if (RTE_I2S0_TX_SCK_PIN_EN == 1U)
  183. &I2S0_pin_tx_sck,
  184. #else
  185. NULL,
  186. #endif
  187. #if (RTE_I2S0_TX_WS_PIN_EN == 1U)
  188. &I2S0_pin_tx_ws,
  189. #else
  190. NULL,
  191. #endif
  192. #if (RTE_I2S0_TX_SDA_PIN_EN == 1U)
  193. &I2S0_pin_tx_sda,
  194. #else
  195. NULL,
  196. #endif
  197. #if (RTE_I2S0_TX_MCLK_PIN_EN == 1U)
  198. &I2S0_pin_tx_mclk,
  199. #else
  200. NULL,
  201. #endif
  202. },
  203. I2S0_IRQn,
  204. #if (RTE_I2S0_DMA_TX_EN == 1U)
  205. &I2S0_DMA_Tx,
  206. #else
  207. NULL,
  208. #endif
  209. #if (RTE_I2S0_DMA_RX_EN == 1U)
  210. &I2S0_DMA_Rx,
  211. #else
  212. NULL,
  213. #endif
  214. (uint8_t) I2S0_TX_FIFO_LEVEL,
  215. (uint8_t) I2S0_RX_FIFO_LEVEL,
  216. &I2S0_Info
  217. };
  218. #endif
  219. // I2S1
  220. #if (RTE_I2S1)
  221. static I2S_INFO I2S1_Info = {0};
  222. #if (RTE_I2S1_RX_SCK_PIN_EN == 1U)
  223. static PIN_ID I2S1_pin_rx_sck = { RTE_I2S1_RX_SCK_PORT, RTE_I2S1_RX_SCK_BIT, RTE_I2S1_RX_SCK_FUNC };
  224. #endif
  225. #if (RTE_I2S1_RX_WS_PIN_EN == 1U)
  226. static PIN_ID I2S1_pin_rx_ws = { RTE_I2S1_RX_WS_PORT, RTE_I2S1_RX_WS_BIT, RTE_I2S1_RX_WS_FUNC };
  227. #endif
  228. #if (RTE_I2S1_RX_SDA_PIN_EN == 1U)
  229. static PIN_ID I2S1_pin_rx_sda = { RTE_I2S1_RX_SDA_PORT, RTE_I2S1_RX_SDA_BIT, RTE_I2S1_RX_SDA_FUNC };
  230. #endif
  231. #if (RTE_I2S1_RX_MCLK_PIN_EN == 1U)
  232. static PIN_ID I2S1_pin_rx_mclk = { RTE_I2S1_RX_MCLK_PORT, RTE_I2S1_RX_MCLK_BIT, RTE_I2S1_RX_MCLK_FUNC };
  233. #endif
  234. #if (RTE_I2S1_TX_SCK_PIN_EN == 1U)
  235. static PIN_ID I2S1_pin_tx_sck = { RTE_I2S1_TX_SCK_PORT, RTE_I2S1_TX_SCK_BIT, RTE_I2S1_TX_SCK_FUNC };
  236. #endif
  237. #if (RTE_I2S1_TX_WS_PIN_EN == 1U)
  238. static PIN_ID I2S1_pin_tx_ws = { RTE_I2S1_TX_WS_PORT, RTE_I2S1_TX_WS_BIT, RTE_I2S1_TX_WS_FUNC };
  239. #endif
  240. #if (RTE_I2S1_TX_SDA_PIN_EN == 1U)
  241. static PIN_ID I2S1_pin_tx_sda = { RTE_I2S1_TX_SDA_PORT, RTE_I2S1_TX_SDA_BIT, RTE_I2S1_TX_SDA_FUNC };
  242. #endif
  243. #if (RTE_I2S1_TX_MCLK_PIN_EN == 1U)
  244. static PIN_ID I2S1_pin_tx_mclk = { RTE_I2S1_TX_MCLK_PORT, RTE_I2S1_TX_MCLK_BIT, RTE_I2S1_TX_MCLK_FUNC };
  245. #endif
  246. #if (RTE_I2S1_DMA_TX_EN == 1U)
  247. void I2S1_GPDMA_Tx_Event (uint32_t event);
  248. static I2S_DMA I2S1_DMA_Tx = {RTE_I2S1_DMA_TX_CH,
  249. RTE_I2S1_DMA_TX_PERI,
  250. RTE_I2S1_DMA_TX_PERI_SEL,
  251. I2S1_GPDMA_Tx_Event};
  252. #endif
  253. #if (RTE_I2S1_DMA_RX_EN == 1U)
  254. void I2S1_GPDMA_Rx_Event (uint32_t event);
  255. static I2S_DMA I2S1_DMA_Rx = {RTE_I2S1_DMA_RX_CH,
  256. RTE_I2S1_DMA_RX_PERI,
  257. RTE_I2S1_DMA_RX_PERI_SEL,
  258. I2S1_GPDMA_Rx_Event};
  259. #endif
  260. static const I2S_RESOURCES I2S1_Resources = {
  261. { // Capabilities
  262. 1, ///< supports asynchronous Transmit/Receive
  263. 1, ///< supports synchronous Transmit/Receive
  264. 0, ///< supports user defined Protocol
  265. 1, ///< supports I2S Protocol
  266. 0, ///< supports MSB/LSB justified Protocol
  267. 0, ///< supports PCM short/long frame Protocol
  268. 0, ///< supports AC'97 Protocol
  269. 1, ///< supports Mono mode
  270. 0, ///< supports Companding
  271. #if ((RTE_I2S1_TX_MCLK_PIN_EN == 1U) && (RTE_I2S1_RX_MCLK_PIN_EN == 1U))
  272. 1, ///< supports MCLK (Master Clock) pin
  273. #else
  274. 0, ///< supports MCLK (Master Clock) pin
  275. #endif
  276. 0, ///< supports Frame error event: \ref ARM_SAI_EVENT_FRAME_ERROR
  277. },
  278. LPC_I2S1,
  279. { // I2S1 RX Pin configuration
  280. #if (RTE_I2S1_RX_SCK_PIN_EN == 1U)
  281. &I2S1_pin_rx_sck,
  282. #else
  283. NULL,
  284. #endif
  285. #if (RTE_I2S1_RX_WS_PIN_EN == 1U)
  286. &I2S1_pin_rx_ws,
  287. #else
  288. NULL,
  289. #endif
  290. #if (RTE_I2S1_RX_SDA_PIN_EN == 1U)
  291. &I2S1_pin_rx_sda,
  292. #else
  293. NULL,
  294. #endif
  295. #if (RTE_I2S1_RX_MCLK_PIN_EN == 1U)
  296. &I2S1_pin_rx_mclk,
  297. #else
  298. NULL,
  299. #endif
  300. },
  301. { // I2S1 RX Pin configuration
  302. #if (RTE_I2S1_TX_SCK_PIN_EN == 1U)
  303. &I2S1_pin_tx_sck,
  304. #else
  305. NULL,
  306. #endif
  307. #if (RTE_I2S1_TX_WS_PIN_EN == 1U)
  308. &I2S1_pin_tx_ws,
  309. #else
  310. NULL,
  311. #endif
  312. #if (RTE_I2S1_TX_SDA_PIN_EN == 1U)
  313. &I2S1_pin_tx_sda,
  314. #else
  315. NULL,
  316. #endif
  317. #if (RTE_I2S1_TX_MCLK_PIN_EN == 1U)
  318. &I2S1_pin_tx_mclk,
  319. #else
  320. NULL,
  321. #endif
  322. },
  323. I2S1_IRQn,
  324. #if (RTE_I2S1_DMA_TX_EN == 1U)
  325. &I2S1_DMA_Tx,
  326. #else
  327. NULL,
  328. #endif
  329. #if (RTE_I2S1_DMA_RX_EN == 1U)
  330. &I2S1_DMA_Rx,
  331. #else
  332. NULL,
  333. #endif
  334. (uint8_t) I2S1_TX_FIFO_LEVEL,
  335. (uint8_t) I2S1_RX_FIFO_LEVEL,
  336. &I2S1_Info
  337. };
  338. #endif
  339. // Extern Function
  340. extern uint32_t GetClockFreq (uint32_t clk_src);
  341. /*
  342. \fn static void i2s_dec2fract (double dec, uint8_t* xret, uint8_t* yret)
  343. \brief convert a decimal to a fraction for x/y baudrate factor
  344. \details Use continued fractions to find matching fraction
  345. http://en.wikipedia.org/wiki/Generalized_continued_fraction
  346. \param[in] dec Decimal fraction as floating point
  347. \param[in] xret pointer to numerator result
  348. \param[in] yret pointer to denominator result
  349. */
  350. static void i2s_dec2fract (double dec, uint8_t* xret, uint8_t* yret) {
  351. int_fast64_t a, tmp, idec;
  352. int_fast64_t n = 1;
  353. int_fast64_t f[3] = { 0, 1, 0 };
  354. int_fast64_t g[3] = { 1, 0, 0 };
  355. int i;
  356. //Expand float input
  357. while (dec != floor(dec)) { n <<= 1; dec *= 2; }
  358. idec = dec;
  359. //continue fraction
  360. for (i = 0; i < 64; i++) {
  361. a = n ? idec / n : 0;
  362. if (i && !a) break;
  363. tmp = idec;
  364. idec = n;
  365. n = tmp % n;
  366. tmp = a;
  367. //check denominator
  368. if (g[1] * a + g[0] >= D2F_DOMAIN) {
  369. tmp = (D2F_DOMAIN - g[0]) / g[1];
  370. if (tmp * 2 >= a || g[1] >= D2F_DOMAIN) { i = 65; }
  371. else { break; }
  372. }
  373. f[2] = tmp * f[1] + f[0];
  374. f[0] = f[1];
  375. f[1] = f[2];
  376. g[2] = tmp * g[1] + g[0];
  377. g[0] = g[1];
  378. g[1] = g[2];
  379. }
  380. *yret = g[1];
  381. *xret = f[1];
  382. }
  383. /**
  384. \fn ARM_DRIVER_VERSION I2Sx_GetVersion (void)
  385. \brief Get driver version.
  386. \return \ref ARM_DRIVER_VERSION
  387. */
  388. static ARM_DRIVER_VERSION I2Sx_GetVersion (void) {
  389. return (DriverVersion);
  390. }
  391. /**
  392. \fn ARM_SAI_CAPABILITIES I2Sx_GetCapabilities (void)
  393. \brief Get driver capabilities.
  394. \param[in] i2s Pointer to I2S resources
  395. \return \ref ARM_SAI_CAPABILITIES
  396. */
  397. static ARM_SAI_CAPABILITIES I2S_GetCapabilities (I2S_RESOURCES *i2s) {
  398. return (i2s->capabilities);
  399. }
  400. /**
  401. \fn int32_t I2S_Initialize (ARM_SAI_SignalEvent_t cb_event, I2S_RESOURCES *i2s)
  402. \brief Initialize I2S Interface.
  403. \param[in] cb_event Pointer to \ref ARM_SAI_SignalEvent
  404. \param[in] i2s Pointer to I2S resources
  405. \return \ref execution_status
  406. */
  407. static int32_t I2S_Initialize (ARM_SAI_SignalEvent_t cb_event, I2S_RESOURCES *i2s) {
  408. if (i2s->info->flags & I2S_FLAG_INITIALIZED) {
  409. // Driver is already initialized
  410. return ARM_DRIVER_OK;
  411. }
  412. // Initialize I2S Run-Time resources
  413. i2s->info->cb_event = cb_event;
  414. i2s->info->status.frame_error = 0U;
  415. i2s->info->status.rx_busy = 0U;
  416. i2s->info->status.rx_overflow = 0U;
  417. i2s->info->status.tx_busy = 0U;
  418. i2s->info->status.tx_underflow = 0U;
  419. // Configure RX SCK pin
  420. if (i2s->rx_pins.sck != NULL) {
  421. if (i2s->rx_pins.sck->port == 0x10U) {
  422. // CLK1, CLK2 or CLK3
  423. SCU_CLK_PinConfigure (i2s->rx_pins.sck->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  424. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.sck->config_val));
  425. } else {
  426. SCU_PinConfigure(i2s->rx_pins.sck->port, i2s->rx_pins.sck->num,
  427. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  428. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.sck->config_val));
  429. }
  430. }
  431. // Configure RX WS pin
  432. if (i2s->rx_pins.ws != NULL) {
  433. if (i2s->rx_pins.ws->port == 0x10U) {
  434. // CLK1, CLK2 or CLK3
  435. SCU_CLK_PinConfigure (i2s->rx_pins.ws->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  436. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.ws->config_val));
  437. } else {
  438. SCU_PinConfigure(i2s->rx_pins.ws->port, i2s->rx_pins.ws->num,
  439. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  440. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.ws->config_val));
  441. }
  442. }
  443. // Configure RX SDA pin
  444. if (i2s->rx_pins.sda != NULL) {
  445. if (i2s->rx_pins.sda->port == 0x10U) {
  446. // CLK1, CLK2 or CLK3
  447. SCU_CLK_PinConfigure (i2s->rx_pins.sda->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  448. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.sda->config_val));
  449. } else {
  450. SCU_PinConfigure(i2s->rx_pins.sda->port, i2s->rx_pins.sda->num,
  451. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  452. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.sda->config_val));
  453. }
  454. }
  455. // Configure RX MCLK pin
  456. if (i2s->rx_pins.mclk != NULL) {
  457. if (i2s->rx_pins.mclk->port == 0x10U) {
  458. // CLK1, CLK2 or CLK3
  459. SCU_CLK_PinConfigure (i2s->rx_pins.mclk->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  460. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.mclk->config_val));
  461. } else {
  462. SCU_PinConfigure(i2s->rx_pins.mclk->port, i2s->rx_pins.mclk->num,
  463. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  464. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->rx_pins.mclk->config_val));
  465. }
  466. }
  467. // Configure TX SCK pin
  468. if (i2s->tx_pins.sck != NULL) {
  469. if (i2s->tx_pins.sck->port == 0x10U) {
  470. // CLK1, CLK2 or CLK3
  471. SCU_CLK_PinConfigure (i2s->tx_pins.sck->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  472. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.sck->config_val));
  473. } else {
  474. SCU_PinConfigure(i2s->tx_pins.sck->port, i2s->tx_pins.sck->num,
  475. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  476. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.sck->config_val));
  477. }
  478. }
  479. // Configure TX WS pin
  480. if (i2s->tx_pins.ws != NULL) {
  481. if (i2s->tx_pins.ws->port == 0x10U) {
  482. // CLK1, CLK2 or CLK3
  483. SCU_CLK_PinConfigure (i2s->tx_pins.ws->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  484. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.ws->config_val));
  485. } else {
  486. SCU_PinConfigure(i2s->tx_pins.ws->port, i2s->tx_pins.ws->num,
  487. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  488. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.ws->config_val));
  489. }
  490. }
  491. // Configure TX SDA pin
  492. if (i2s->tx_pins.sda != NULL) {
  493. if (i2s->tx_pins.sda->port == 0x10U) {
  494. // CLK1, CLK2 or CLK3
  495. SCU_CLK_PinConfigure (i2s->tx_pins.sda->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  496. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.sda->config_val));
  497. } else {
  498. SCU_PinConfigure(i2s->tx_pins.sda->port, i2s->tx_pins.sda->num,
  499. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  500. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.sda->config_val));
  501. }
  502. }
  503. // Configure TX MCLK pin
  504. if (i2s->tx_pins.mclk != NULL) {
  505. if (i2s->tx_pins.mclk->port == 0x10U) {
  506. // CLK1, CLK2 or CLK3
  507. SCU_CLK_PinConfigure (i2s->tx_pins.mclk->num, SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  508. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.mclk->config_val));
  509. } else {
  510. SCU_PinConfigure(i2s->tx_pins.mclk->port, i2s->tx_pins.mclk->num,
  511. SCU_PIN_CFG_INPUT_FILTER_DIS | SCU_PIN_CFG_INPUT_BUFFER_EN |
  512. SCU_PIN_CFG_PULLUP_DIS | SCU_PIN_CFG_MODE(i2s->tx_pins.mclk->config_val));
  513. }
  514. }
  515. // DMA Initialize
  516. if ((i2s->dma_tx != NULL) || (i2s->dma_rx != NULL)) {
  517. GPDMA_Initialize ();
  518. }
  519. i2s->info->flags = I2S_FLAG_INITIALIZED;
  520. return ARM_DRIVER_OK;
  521. }
  522. /**
  523. \fn int32_t I2S_Uninitialize (I2S_RESOURCES *i2s)
  524. \brief De-initialize I2S Interface.
  525. \param[in] i2s Pointer to I2S resources
  526. \return \ref execution_status
  527. */
  528. static int32_t I2S_Uninitialize (I2S_RESOURCES *i2s) {
  529. // Reset RX SCK pin Configuration
  530. if (i2s->rx_pins.sck != NULL) {
  531. if (i2s->rx_pins.sck->port == 0x10U) {
  532. // CLK1, CLK2 or CLK3
  533. SCU_CLK_PinConfigure (i2s->rx_pins.sck->num, 0);
  534. } else {
  535. SCU_PinConfigure(i2s->rx_pins.sck->port, i2s->rx_pins.sck->num, 0);
  536. }
  537. }
  538. // Reset RX WS pin Configuration
  539. if (i2s->rx_pins.ws != NULL) {
  540. if (i2s->rx_pins.ws->port == 0x10U) {
  541. // CLK1, CLK2 or CLK3
  542. SCU_CLK_PinConfigure (i2s->rx_pins.ws->num, 0);
  543. } else {
  544. SCU_PinConfigure(i2s->rx_pins.ws->port, i2s->rx_pins.ws->num, 0);
  545. }
  546. }
  547. // Reset RX SDA pin Configuration
  548. if (i2s->rx_pins.sda != NULL) {
  549. if (i2s->rx_pins.sda->port == 0x10U) {
  550. // CLK1, CLK2 or CLK3
  551. SCU_CLK_PinConfigure (i2s->rx_pins.sda->num, 0);
  552. } else {
  553. SCU_PinConfigure(i2s->rx_pins.sda->port, i2s->rx_pins.sda->num, 0);
  554. }
  555. }
  556. // Reset RX MCLK pin Configuration
  557. if (i2s->rx_pins.mclk != NULL) {
  558. if (i2s->rx_pins.mclk->port == 0x10U) {
  559. // CLK1, CLK2 or CLK3
  560. SCU_CLK_PinConfigure (i2s->rx_pins.mclk->num, 0);
  561. } else {
  562. SCU_PinConfigure(i2s->rx_pins.mclk->port, i2s->rx_pins.mclk->num, 0);
  563. }
  564. }
  565. // Reset TX SCK pin Configuration
  566. if (i2s->tx_pins.sck != NULL) {
  567. if (i2s->tx_pins.sck->port == 0x10U) {
  568. // CLK1, CLK2 or CLK3
  569. SCU_CLK_PinConfigure (i2s->tx_pins.sck->num, 0);
  570. } else {
  571. SCU_PinConfigure(i2s->tx_pins.sck->port, i2s->tx_pins.sck->num, 0);
  572. }
  573. }
  574. // Reset TX WS pin Configuration
  575. if (i2s->tx_pins.ws != NULL) {
  576. if (i2s->tx_pins.ws->port == 0x10U) {
  577. // CLK1, CLK2 or CLK3
  578. SCU_CLK_PinConfigure (i2s->tx_pins.ws->num, 0);
  579. } else {
  580. SCU_PinConfigure(i2s->tx_pins.ws->port, i2s->tx_pins.ws->num, 0);
  581. }
  582. }
  583. // Reset TX SDA pin Configuration
  584. if (i2s->tx_pins.sda != NULL) {
  585. if (i2s->tx_pins.sda->port == 0x10U) {
  586. // CLK1, CLK2 or CLK3
  587. SCU_CLK_PinConfigure (i2s->tx_pins.sda->num, 0);
  588. } else {
  589. SCU_PinConfigure(i2s->tx_pins.sda->port, i2s->tx_pins.sda->num, 0);
  590. }
  591. }
  592. // Reset TX MCLK pin Configuration
  593. if (i2s->tx_pins.mclk != NULL) {
  594. if (i2s->tx_pins.mclk->port == 0x10U) {
  595. // CLK1, CLK2 or CLK3
  596. SCU_CLK_PinConfigure (i2s->tx_pins.mclk->num, 0);
  597. } else {
  598. SCU_PinConfigure(i2s->tx_pins.mclk->port, i2s->tx_pins.mclk->num, 0);
  599. }
  600. }
  601. // DMA Uninitialize
  602. if ((i2s->dma_tx != NULL) || (i2s->dma_rx != NULL)) { GPDMA_Uninitialize (); }
  603. // Reset I2S status flags
  604. i2s->info->flags = 0U;
  605. return ARM_DRIVER_OK;
  606. }
  607. /**
  608. \fn int32_t I2S_PowerControl (ARM_POWER_STATE state, I2S_RESOURCES *i2s)
  609. \brief Control I2S Interface Power.
  610. \param[in] state Power state
  611. \param[in] i2s Pointer to I2S resources
  612. \return \ref execution_status
  613. */
  614. static int32_t I2S_PowerControl (ARM_POWER_STATE state, I2S_RESOURCES *i2s) {
  615. switch (state) {
  616. case ARM_POWER_OFF:
  617. // Disable I2S IRQ
  618. NVIC_DisableIRQ(i2s->irq_num);
  619. if ((i2s->dma_tx == NULL) && (i2s->info->status.tx_busy != 0U)) {
  620. // Disable DMA channel
  621. GPDMA_ChannelDisable (i2s->dma_tx->channel);
  622. }
  623. if ((i2s->dma_rx == NULL) && (i2s->info->status.rx_busy != 0U)) {
  624. // Disable DMA channel
  625. GPDMA_ChannelDisable (i2s->dma_rx->channel);
  626. }
  627. // Reset I2S peripheral
  628. LPC_RGU->RESET_CTRL1 = (1U << 20) | (~(LPC_RGU->RESET_ACTIVE_STATUS1));
  629. while ((LPC_RGU->RESET_ACTIVE_STATUS1 & (1U << 20)) == 0U);
  630. // Disable I2S peripheral clock
  631. LPC_CCU2->CLK_APLL_CFG &= ~CCU_CLK_CFG_RUN;
  632. // Clear pending I2S interrupts in NVIC
  633. NVIC_ClearPendingIRQ(i2s->irq_num);
  634. // Clear driver variables
  635. i2s->info->status.frame_error = 0U;
  636. i2s->info->status.rx_busy = 0U;
  637. i2s->info->status.rx_overflow = 0U;
  638. i2s->info->status.tx_busy = 0U;
  639. i2s->info->status.tx_underflow = 0U;
  640. i2s->info->flags &= ~I2S_FLAG_POWERED;
  641. break;
  642. case ARM_POWER_LOW:
  643. return ARM_DRIVER_ERROR_UNSUPPORTED;
  644. case ARM_POWER_FULL:
  645. if ((i2s->info->flags & I2S_FLAG_INITIALIZED) == 0U) { return ARM_DRIVER_ERROR; }
  646. if ((i2s->info->flags & I2S_FLAG_POWERED) != 0U) { return ARM_DRIVER_OK; }
  647. // Select PLL1 for APB1 clk source and enable autoblock
  648. LPC_CGU->BASE_APB1_CLK = (9U << 24) | (1U << 11);
  649. // Enable I2S peripheral clock
  650. LPC_CCU2->CLK_APLL_CFG |= CCU_CLK_CFG_AUTO | CCU_CLK_CFG_RUN;
  651. while ((LPC_CCU2->CLK_APLL_STAT & CCU_CLK_CFG_RUN) == 0U);
  652. // Reset I2S peripheral
  653. LPC_RGU->RESET_CTRL1 = (1U << 20) | (~(LPC_RGU->RESET_ACTIVE_STATUS1));
  654. while ((LPC_RGU->RESET_ACTIVE_STATUS1 & (1U << 20)) == 0U);
  655. // I2S0 and I2S1 RX_SCK and TX_SCK are defined by RXMODE and TXMODE registers
  656. LPC_CREG->CREG6 &= ~ (0x0FU << 12);
  657. // Disable I2S interrupts
  658. i2s->reg->IRQ &= ~(I2S_IRQ_RX_IRQ_ENABLE | I2S_IRQ_TX_IRQ_ENABLE);
  659. // Stop transmitter and receiver
  660. i2s->reg->DAO |= (I2S_DAO_DAI_STOP | I2S_DAO_DAI_WS_SEL);
  661. i2s->reg->DAI |= (I2S_DAO_DAI_STOP | I2S_DAO_DAI_WS_SEL);
  662. // Clear driver variables
  663. i2s->info->status.frame_error = 0U;
  664. i2s->info->status.rx_busy = 0U;
  665. i2s->info->status.rx_overflow = 0U;
  666. i2s->info->status.tx_busy = 0U;
  667. i2s->info->status.tx_underflow = 0U;
  668. i2s->info->rx.residue_cnt = 0U;
  669. i2s->info->rx.residue_num = 0U;
  670. i2s->info->tx.residue_cnt = 0U;
  671. i2s->info->tx.residue_num = 0U;
  672. i2s->info->flags = I2S_FLAG_POWERED | I2S_FLAG_INITIALIZED;
  673. // Clear and Enable SAI IRQ
  674. NVIC_ClearPendingIRQ(i2s->irq_num);
  675. NVIC_EnableIRQ(i2s->irq_num);
  676. break;
  677. default: return ARM_DRIVER_ERROR_UNSUPPORTED;
  678. }
  679. return ARM_DRIVER_OK;
  680. }
  681. /**
  682. \fn int32_t I2S_Send (const void *data, uint32_t num, I2S_RESOURCES *i2s)
  683. \brief Start sending data to I2S transmitter.
  684. \param[in] data Pointer to buffer with data to send to I2S transmitter
  685. \param[in] num Number of data items to send
  686. \param[in] i2s Pointer to I2S resources
  687. \return \ref execution_status
  688. */
  689. static int32_t I2S_Send (const void *data, uint32_t num, I2S_RESOURCES *i2s) {
  690. uint32_t val;
  691. int32_t stat;
  692. if ((data == NULL) || (num == 0U)) {
  693. // Invalid parameters
  694. return ARM_DRIVER_ERROR_PARAMETER;
  695. }
  696. if ((i2s->info->flags & I2S_FLAG_CONFIGURED) == 0U) {
  697. // I2S is not configured (mode not selected)
  698. return ARM_DRIVER_ERROR;
  699. }
  700. if (i2s->info->status.tx_busy) {
  701. // Send is not completed yet
  702. return ARM_DRIVER_ERROR_BUSY;
  703. }
  704. // Set Send active flag
  705. i2s->info->status.tx_busy = 1U;
  706. // Clear TX underflow flag
  707. i2s->info->status.tx_underflow = 0U;
  708. // Save transmit buffer info
  709. i2s->info->tx.buf = (uint8_t *)data;
  710. i2s->info->tx.cnt = 0U;
  711. // Convert from number of samples to number of bytes
  712. num = num * (i2s->info->tx.data_bits / 8U);
  713. // Only 32-bit value can be written to FIFO. If there is data left from last send,
  714. // fill residue buffer to 32bits and write to TX FIFO
  715. if (i2s->info->tx.residue_cnt != 0U) {
  716. while ((i2s->info->tx.residue_cnt < 4U) && (i2s->info->tx.cnt < num)) {
  717. i2s->info->tx.residue_buf[i2s->info->tx.residue_cnt++] = i2s->info->tx.buf[i2s->info->tx.cnt++];
  718. }
  719. if (i2s->info->tx.residue_cnt == 4U) {
  720. // Write 32bits to TX FIFO
  721. i2s->reg->TXFIFO = *(__packed uint32_t *)(i2s->info->tx.residue_buf);
  722. // There is no valid data in residue buffer
  723. i2s->info->tx.residue_cnt = 0U;
  724. }
  725. }
  726. // Disable I2S transmitter interrupt
  727. i2s->reg->IRQ &= ~I2S_IRQ_TX_IRQ_ENABLE;
  728. i2s->info->tx.num = num;
  729. // DMA mode
  730. if (i2s->dma_tx != NULL) {
  731. num -= i2s->info->tx.cnt;
  732. if (num < 4U) {
  733. // Enable I2S transmitter interrupt
  734. i2s->reg->IRQ |= I2S_IRQ_TX_IRQ_ENABLE;
  735. } else {
  736. // Configure DMA mux
  737. GPDMA_PeripheralSelect (i2s->dma_tx->peripheral, i2s->dma_tx->peripheral_sel);
  738. // Configure DMA channel
  739. stat = GPDMA_ChannelConfigure (i2s->dma_tx->channel,
  740. (uint32_t)i2s->info->tx.buf + i2s->info->tx.cnt,
  741. (uint32_t)(&(i2s->reg->TXFIFO)),
  742. num / 4U,
  743. GPDMA_CH_CONTROL_SBSIZE(GPDMA_BSIZE_1) |
  744. GPDMA_CH_CONTROL_DBSIZE(GPDMA_BSIZE_1) |
  745. GPDMA_CH_CONTROL_SWIDTH(GPDMA_WIDTH_WORD) |
  746. GPDMA_CH_CONTROL_DWIDTH(GPDMA_WIDTH_WORD) |
  747. GPDMA_CH_CONTROL_S |
  748. GPDMA_CH_CONTROL_D |
  749. GPDMA_CH_CONTROL_I |
  750. GPDMA_CH_CONTROL_SI,
  751. GPDMA_CH_CONFIG_DEST_PERI(i2s->dma_tx->peripheral) |
  752. GPDMA_CH_CONFIG_FLOWCNTRL(GPDMA_TRANSFER_M2P_CTRL_DMA) |
  753. GPDMA_CH_CONFIG_IE |
  754. GPDMA_CH_CONFIG_ITC |
  755. GPDMA_CH_CONFIG_E,
  756. i2s->dma_tx->cb_event);
  757. if (stat == -1) { return ARM_DRIVER_ERROR; }
  758. // Set FIFO level and enable TX DMA
  759. i2s->reg->DMA1 = (((i2s->tx_fifo_level << I2S_DMA_TX_DEPTH_DMA_POS) & I2S_DMA_TX_DEPTH_DMA_MSK) |
  760. (I2S_DMA_TX_DMA_ENABLE));
  761. }
  762. // Interrupt mode
  763. } else {
  764. // Set FIFO level, to trigger TX interrupt
  765. val = i2s->reg->IRQ & ~I2S_IRQ_TX_DEPTH_IRQ_MSK;
  766. val |= (i2s->tx_fifo_level << I2S_IRQ_TX_DEPTH_IRQ_POS) & I2S_IRQ_TX_DEPTH_IRQ_MSK;
  767. i2s->reg->IRQ = val;
  768. // Enable I2S transmitter interrupt
  769. i2s->reg->IRQ |= I2S_IRQ_TX_IRQ_ENABLE;
  770. }
  771. return ARM_DRIVER_OK;
  772. }
  773. /**
  774. \fn int32_t I2S_Receive (void *data, uint32_t num, I2S_RESOURCES *i2s)
  775. \brief Start receiving data from I2S receiver.
  776. \param[out] data Pointer to buffer for data to receive from I2S receiver
  777. \param[in] num Number of data items to receive
  778. \param[in] i2s Pointer to I2S resources
  779. \return \ref execution_status
  780. */
  781. static int32_t I2S_Receive (void *data, uint32_t num, I2S_RESOURCES *i2s) {
  782. uint32_t val, offset;
  783. int32_t stat;
  784. if ((data == NULL) || (num == 0U)) {
  785. // Invalid parameters
  786. return ARM_DRIVER_ERROR_PARAMETER;
  787. }
  788. if ((i2s->info->flags & I2S_FLAG_CONFIGURED) == 0U) {
  789. // I2S is not configured (mode not selected)
  790. return ARM_DRIVER_ERROR;
  791. }
  792. if (i2s->info->status.rx_busy) {
  793. // Receive is not completed yet
  794. return ARM_DRIVER_ERROR_BUSY;
  795. }
  796. // Set Receive active flag
  797. i2s->info->status.rx_busy = 1U;
  798. // Clear RX overflow flag
  799. i2s->info->status.rx_overflow = 0U;
  800. // Save receive buffer info
  801. i2s->info->rx.buf = (uint8_t *)data;
  802. i2s->info->rx.cnt = 0U;
  803. // Convert from number of samples to number of bytes
  804. num = num * (i2s->info->rx.data_bits / 8U);
  805. while ((i2s->info->rx.cnt < num) && (i2s->info->rx.residue_cnt < i2s->info->rx.residue_num)) {
  806. // RX Data available in residue buffer
  807. i2s->info->rx.buf[i2s->info->rx.cnt++] = i2s->info->rx.residue_buf[i2s->info->rx.residue_cnt++];
  808. if (i2s->info->rx.residue_cnt == i2s->info->rx.residue_num) {
  809. // Residue buffer empty
  810. i2s->info->rx.residue_cnt = 0U;
  811. i2s->info->rx.residue_num = 0U;
  812. }
  813. }
  814. // Disable I2S receive interrupt
  815. i2s->reg->IRQ &= ~I2S_IRQ_RX_IRQ_ENABLE;
  816. i2s->info->rx.num = num;
  817. num -= i2s->info->rx.cnt;
  818. // DMA mode
  819. if ((i2s->dma_rx != NULL) && (num >= 4U)) {
  820. // Set offset in RX Buffer for DMA transfer
  821. offset = i2s->info->rx.cnt;
  822. // Update RX count
  823. num /= 4;
  824. i2s->info->rx.cnt += num * 4;
  825. // Configure DMA mux
  826. GPDMA_PeripheralSelect (i2s->dma_rx->peripheral, i2s->dma_rx->peripheral_sel);
  827. // Configure DMA channel
  828. stat = GPDMA_ChannelConfigure (i2s->dma_rx->channel,
  829. (uint32_t)(&(i2s->reg->RXFIFO)),
  830. (uint32_t)i2s->info->rx.buf + offset,
  831. num,
  832. GPDMA_CH_CONTROL_SBSIZE(GPDMA_BSIZE_1) |
  833. GPDMA_CH_CONTROL_DBSIZE(GPDMA_BSIZE_1) |
  834. GPDMA_CH_CONTROL_SWIDTH(GPDMA_WIDTH_WORD) |
  835. GPDMA_CH_CONTROL_DWIDTH(GPDMA_WIDTH_WORD) |
  836. GPDMA_CH_CONTROL_S |
  837. GPDMA_CH_CONTROL_D |
  838. GPDMA_CH_CONTROL_I |
  839. GPDMA_CH_CONTROL_DI,
  840. GPDMA_CH_CONFIG_SRC_PERI(i2s->dma_rx->peripheral) |
  841. GPDMA_CH_CONFIG_FLOWCNTRL(GPDMA_TRANSFER_P2M_CTRL_DMA) |
  842. GPDMA_CH_CONFIG_IE |
  843. GPDMA_CH_CONFIG_ITC |
  844. GPDMA_CH_CONFIG_E,
  845. i2s->dma_rx->cb_event);
  846. if (stat == -1) { return ARM_DRIVER_ERROR; }
  847. // Set FIFO level and enable RX DMA
  848. i2s->reg->DMA2 = (((i2s->rx_fifo_level << I2S_DMA_RX_DEPTH_DMA_POS) & I2S_DMA_RX_DEPTH_DMA_MSK) |
  849. (I2S_DMA_RX_DMA_ENABLE));
  850. // Interrupt mode
  851. } else {
  852. // Set FIFO level, to trigger RX interrupt
  853. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  854. val |= (i2s->rx_fifo_level << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  855. i2s->reg->IRQ = val;
  856. // Enable I2S receive interrupt
  857. i2s->reg->IRQ |= I2S_IRQ_RX_IRQ_ENABLE;
  858. }
  859. return ARM_DRIVER_OK;
  860. }
  861. /**
  862. \fn uint32_t I2S_GetTxCount (I2S_RESOURCES *i2s)
  863. \brief Get transmitted data count.
  864. \param[in] i2s Pointer to I2S resources
  865. \return number of data items transmitted
  866. */
  867. static uint32_t I2S_GetTxCount (I2S_RESOURCES *i2s) {
  868. uint32_t cnt;
  869. // Convert count in bytes to count of samples
  870. cnt = i2s->info->tx.cnt / (i2s->info->tx.data_bits / 8U);
  871. return (cnt);
  872. }
  873. /**
  874. \fn uint32_t I2S_GetRxCount (I2S_RESOURCES *i2s)
  875. \brief Get received data count.
  876. \param[in] i2s Pointer to I2S resources
  877. \return number of data items received
  878. */
  879. static uint32_t I2S_GetRxCount (I2S_RESOURCES *i2s) {
  880. uint32_t cnt;
  881. // Convert count in bytes to count of samples
  882. cnt = i2s->info->rx.cnt / (i2s->info->rx.data_bits / 8U);
  883. return (cnt);
  884. }
  885. /**
  886. \fn int32_t I2S_Control (uint32_t control, uint32_t arg1, uint32_t arg2, I2S_RESOURCES *i2s)
  887. \brief Control I2S Interface.
  888. \param[in] control Operation
  889. \param[in] arg1 Argument 1 of operation (optional)
  890. \param[in] arg2 Argument 2 of operation (optional)
  891. \param[in] i2s Pointer to I2S resources
  892. \return common \ref execution_status and driver specific \ref sai_execution_status
  893. */
  894. static int32_t I2S_Control (uint32_t control, uint32_t arg1, uint32_t arg2, I2S_RESOURCES *i2s) {
  895. uint32_t val, pclk, mclk, master, data_bits;
  896. uint32_t reg_daoi, reg_rate, reg_bitrate, reg_mode;
  897. uint8_t x_best, y_best;
  898. double div_exact, div, delta;
  899. I2S_PINS *pins;
  900. if ((i2s->info->flags & I2S_FLAG_POWERED) == 0U) {
  901. // I2S not powered
  902. return ARM_DRIVER_ERROR;
  903. }
  904. master = 0U;
  905. data_bits = 0U;
  906. reg_daoi = 0U;
  907. reg_rate = 0U;
  908. reg_bitrate = 0U;
  909. reg_mode = 0U;
  910. switch (control & ARM_SAI_CONTROL_Msk) {
  911. case ARM_SAI_CONFIGURE_TX:
  912. pins = &(i2s->tx_pins);
  913. if (pins->sda == NULL) {
  914. // No Tx_SDA pin
  915. return ARM_DRIVER_ERROR;
  916. }
  917. break;
  918. case ARM_SAI_CONFIGURE_RX:
  919. pins = &(i2s->rx_pins);
  920. if (pins->sda == NULL) {
  921. // No Rx_SDA pin
  922. return ARM_DRIVER_ERROR;
  923. }
  924. break;
  925. case ARM_SAI_CONTROL_TX:
  926. if ((arg1 & 1U) == 0U) {
  927. i2s->reg->DAO |= (I2S_DAO_DAI_STOP | I2S_DAO_DAI_WS_SEL );
  928. } else {
  929. if (i2s->info->tx.master) { i2s->reg->DAO &= ~I2S_DAO_DAI_WS_SEL; }
  930. else { i2s->reg->DAO |= I2S_DAO_DAI_WS_SEL; }
  931. // Set Stop
  932. i2s->reg->DAO |= I2S_DAO_DAI_STOP;
  933. if ((i2s->info->status.tx_busy == 0U) || (i2s->dma_tx)) {
  934. // Set TX level to 0
  935. val = i2s->reg->IRQ & ~I2S_IRQ_TX_DEPTH_IRQ_MSK;
  936. val |= (0U << I2S_IRQ_TX_DEPTH_IRQ_POS) & I2S_IRQ_TX_DEPTH_IRQ_MSK;
  937. i2s->reg->IRQ = val;
  938. if (i2s->info->status.tx_busy == 0U) {
  939. // Ready to detect TX underflow
  940. i2s->info->tx.num = 0U;
  941. }
  942. }
  943. // Clear stop
  944. i2s->reg->DAO &= ~I2S_DAO_DAI_STOP;
  945. // Enable I2S transmit interrupt
  946. i2s->reg->IRQ |= I2S_IRQ_TX_IRQ_ENABLE;
  947. }
  948. // Mute
  949. if ((arg1 & 2U) != 0U) { i2s->reg->DAO |= I2S_DAO_MUTE; }
  950. else { i2s->reg->DAO &= ~I2S_DAO_MUTE; }
  951. return ARM_DRIVER_OK;
  952. case ARM_SAI_CONTROL_RX:
  953. if ((arg1 & 1U) == 0U) {
  954. i2s->reg->DAI |= (I2S_DAO_DAI_STOP | I2S_DAO_DAI_WS_SEL);
  955. } else {
  956. if (i2s->info->rx.master) { i2s->reg->DAI &= ~I2S_DAO_DAI_WS_SEL; }
  957. else { i2s->reg->DAI |= I2S_DAO_DAI_WS_SEL; }
  958. // Set Stop
  959. i2s->reg->DAI |= I2S_DAO_DAI_STOP;
  960. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  961. if (i2s->info->status.rx_busy == 0U) {
  962. // Set FIFO level to full, to detect RX overflow
  963. val |= (8U << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  964. i2s->reg->IRQ = val;
  965. // Ready to detect RX overflow
  966. i2s->info->rx.num = 0U;
  967. // Enable I2S receive interrupt
  968. i2s->reg->IRQ |= I2S_IRQ_RX_IRQ_ENABLE;
  969. } else {
  970. if ((i2s->dma_rx != NULL) && ((i2s->reg->DMA2 & I2S_DMA_RX_DMA_ENABLE) == 0U)) {
  971. // Set user RX FIFO level
  972. val |= (i2s->rx_fifo_level << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  973. // Enable I2S receive interrupt
  974. i2s->reg->IRQ |= I2S_IRQ_RX_IRQ_ENABLE;
  975. }
  976. }
  977. // Clear stop
  978. i2s->reg->DAI &= ~I2S_DAO_DAI_STOP;
  979. }
  980. return ARM_DRIVER_OK;
  981. case ARM_SAI_MASK_SLOTS_TX:
  982. return ARM_DRIVER_ERROR;
  983. case ARM_SAI_MASK_SLOTS_RX:
  984. return ARM_DRIVER_ERROR;
  985. case ARM_SAI_ABORT_SEND:
  986. // Disable TX interrupt
  987. i2s->reg->IRQ &= ~I2S_IRQ_TX_IRQ_ENABLE;
  988. if (i2s->dma_tx) {
  989. if (i2s->info->status.tx_busy != 0U) {
  990. // Disable DMA channel
  991. GPDMA_ChannelDisable (i2s->dma_tx->channel);
  992. }
  993. }
  994. // Reset TX FIFO
  995. i2s->reg->DAO |= I2S_DAO_DAI_RESET;
  996. // Reset counters
  997. i2s->info->tx.cnt = 0U;
  998. i2s->info->tx.num = 0U;
  999. i2s->info->tx.residue_cnt = 0U;
  1000. i2s->info->tx.residue_num = 0U;
  1001. // Clear reset FIFO bit
  1002. i2s->reg->DAO &= ~I2S_DAO_DAI_RESET;
  1003. // Clear busy flag
  1004. i2s->info->status.tx_busy = 0U;
  1005. if ((i2s->reg->DAO & I2S_DAO_DAI_STOP) == 0U) {
  1006. // Transmitter is enabled
  1007. // Set FIFO level to full and enable TX interrupt, to detect RX overflow
  1008. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1009. val |= (8U << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1010. i2s->reg->IRQ = val | I2S_IRQ_TX_IRQ_ENABLE;
  1011. }
  1012. return ARM_DRIVER_OK;
  1013. case ARM_SAI_ABORT_RECEIVE:
  1014. // Disable RX interrupt
  1015. i2s->reg->IRQ &= ~I2S_IRQ_RX_IRQ_ENABLE;
  1016. if (i2s->dma_rx) {
  1017. if (i2s->info->status.rx_busy != 0U) {
  1018. // Disable DMA channel
  1019. GPDMA_ChannelDisable (i2s->dma_rx->channel);
  1020. }
  1021. }
  1022. // Reset RX FIFO
  1023. i2s->reg->DAI |= I2S_DAO_DAI_RESET;
  1024. // Reset counters
  1025. i2s->info->rx.cnt = 0U;
  1026. i2s->info->rx.num = 0U;
  1027. i2s->info->rx.residue_cnt = 0U;
  1028. i2s->info->rx.residue_num = 0U;
  1029. // Clear reset FIFO bit
  1030. i2s->reg->DAI &= ~I2S_DAO_DAI_RESET;
  1031. // Clear busy flag
  1032. i2s->info->status.rx_busy = 0U;
  1033. if ((i2s->reg->DAI & I2S_DAO_DAI_STOP) == 0U) {
  1034. // Receiver is enabled
  1035. // Set FIFO level to full and enable RX interrupt, to detect RX overflow
  1036. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1037. val |= (8U << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1038. i2s->reg->IRQ = val | I2S_IRQ_RX_IRQ_ENABLE;
  1039. }
  1040. return ARM_DRIVER_OK;
  1041. default: return ARM_DRIVER_ERROR;
  1042. }
  1043. // Mode
  1044. switch (control & ARM_SAI_MODE_Msk) {
  1045. case ARM_SAI_MODE_MASTER:
  1046. master = 1U;
  1047. break;
  1048. case ARM_SAI_MODE_SLAVE:
  1049. break;
  1050. default: return ARM_DRIVER_ERROR;
  1051. }
  1052. // Synchronization
  1053. switch (control & ARM_SAI_SYNCHRONIZATION_Msk) {
  1054. case ARM_SAI_ASYNCHRONOUS:
  1055. if ((pins->sck == NULL) || (pins->ws == NULL)) {
  1056. // Asynchronous mode requires SCK and WS pins
  1057. return ARM_SAI_ERROR_SYNCHRONIZATION;
  1058. }
  1059. break;
  1060. case ARM_SAI_SYNCHRONOUS:
  1061. if (master == 1U) {
  1062. // Only Slave can be synchronous
  1063. return ARM_SAI_ERROR_SYNCHRONIZATION;
  1064. }
  1065. // 4-pin mode: SCK and WS signals are shared between
  1066. // I2S transmit and receive blocks
  1067. reg_daoi |= I2S_TX_RX_MODE_4PIN;
  1068. break;
  1069. default: return ARM_SAI_ERROR_SYNCHRONIZATION;
  1070. }
  1071. // Protocol
  1072. val = (control & ARM_SAI_PROTOCOL_Msk);
  1073. if (val != ARM_SAI_PROTOCOL_I2S) {
  1074. // Only I2S protocol is supported
  1075. return ARM_SAI_ERROR_PROTOCOL;
  1076. }
  1077. // Data size
  1078. switch ((control & ARM_SAI_DATA_SIZE_Msk) >> ARM_SAI_DATA_SIZE_Pos) {
  1079. case 8-1:
  1080. data_bits = 8;
  1081. // 8-Data bit, WS_HALFPERIOD = DataBit-1 = 7
  1082. reg_daoi |= (7U << I2S_DAO_DAI_WS_HALFPERIOD_POS);
  1083. break;
  1084. case 16-1:
  1085. data_bits = 16;
  1086. // 16-Data bit, WS_HALFPERIOD = DataBit-1 = 15
  1087. reg_daoi |= (1U << I2S_DAO_DAI_WORDWIDTH_POS);
  1088. reg_daoi |= (15U << I2S_DAO_DAI_WS_HALFPERIOD_POS);
  1089. break;
  1090. case 32-1:
  1091. data_bits = 32;
  1092. // 32-Data bit, WS_HALFPERIOD = DataBit-1 = 31
  1093. reg_daoi |= (3U << I2S_DAO_DAI_WORDWIDTH_POS);
  1094. reg_daoi |= (31U << I2S_DAO_DAI_WS_HALFPERIOD_POS);
  1095. break;
  1096. default: return ARM_SAI_ERROR_DATA_SIZE;
  1097. }
  1098. // Mono mode
  1099. if (control & ARM_SAI_MONO_MODE) {
  1100. reg_daoi |= I2S_DAO_DAI_MONO;
  1101. }
  1102. // Companding
  1103. val = control & ARM_SAI_COMPANDING_Msk;
  1104. if (val != ARM_SAI_COMPANDING_NONE) { return ARM_SAI_ERROR_COMPANDING; }
  1105. // Clock polarity
  1106. val = control & ARM_SAI_CLOCK_POLARITY_Msk;
  1107. if (val != ARM_SAI_CLOCK_POLARITY_0) { return ARM_SAI_ERROR_CLOCK_POLARITY; }
  1108. // Master clock pin
  1109. switch (control & ARM_SAI_MCLK_PIN_Msk) {
  1110. case ARM_SAI_MCLK_PIN_INACTIVE:
  1111. break;
  1112. case ARM_SAI_MCLK_PIN_OUTPUT:
  1113. if (pins->mclk == NULL) {
  1114. // MCLK pin is not available
  1115. return ARM_SAI_ERROR_MCLK_PIN;
  1116. }
  1117. // Generate MCLK on MCLK pin
  1118. reg_mode |= I2S_TX_RX_MODE_MCENA;
  1119. break;
  1120. case ARM_SAI_MCLK_PIN_INPUT:
  1121. if (pins->mclk == NULL) {
  1122. // MCLK pin is not available
  1123. return ARM_SAI_ERROR_MCLK_PIN;
  1124. }
  1125. // Audio clock source is MCLK
  1126. reg_mode |= (1U & I2S_TX_RX_MODE_CLKSEL_MSK);
  1127. break;
  1128. default: return ARM_SAI_ERROR_MCLK_PIN;
  1129. }
  1130. // Frame length
  1131. val = ((arg1 & ARM_SAI_FRAME_LENGTH_Msk) >> ARM_SAI_FRAME_LENGTH_Pos) + 1;
  1132. if ((val != 0U) && (val != (data_bits * 2))) { return ARM_SAI_ERROR_FRAME_LENGTH; }
  1133. // Audio Frequency
  1134. if (master == 1U) {
  1135. // WS and SCK are generated only by master
  1136. val = ((arg2 & ARM_SAI_MCLK_PRESCALER_Msk) >> ARM_SAI_MCLK_PRESCALER_Pos) + 1;
  1137. reg_bitrate = val / (data_bits * 2);
  1138. reg_bitrate--;
  1139. if (reg_bitrate > I2S_TX_RX_BITRATE_BITRATE_MSK) { return ARM_SAI_ERROR_MCLK_PRESCALER; }
  1140. if ((reg_mode & (1U & I2S_TX_RX_MODE_CLKSEL_MSK)) == 0U) {
  1141. // Clock source is not MCLK input
  1142. mclk = val * (arg2 & ARM_SAI_AUDIO_FREQ_Msk);
  1143. pclk = GetClockFreq (9);
  1144. // MCLK = pclk * (x/y) /2 ==> (x/y) = 2*MCLK/pclk
  1145. div_exact = (2.0 * mclk) / pclk;
  1146. i2s_dec2fract (div_exact, &x_best, &y_best);
  1147. div = (double)(x_best) / (double)(y_best);
  1148. if (div_exact > div) { delta = div_exact - div; }
  1149. else { delta = div - div_exact; }
  1150. if (((delta * 100U) / div_exact) > I2S_FREQ_TOLERANCE) {return ARM_SAI_ERROR_AUDIO_FREQ; }
  1151. reg_rate = (y_best << I2S_TX_RX_RATE_Y_DIVIDER_POS) | (x_best << I2S_TX_RX_RATE_X_DIVIDER_POS);
  1152. }
  1153. }
  1154. // Save values to registers and globals
  1155. if ((control & ARM_SAI_CONTROL_Msk) == ARM_SAI_CONFIGURE_TX) {
  1156. i2s->info->tx.data_bits = data_bits;
  1157. i2s->info->tx.master = master;
  1158. i2s->reg->TXRATE = reg_rate;
  1159. i2s->reg->TXBITRATE = reg_bitrate;
  1160. i2s->reg->TXMODE = reg_mode;
  1161. reg_daoi |= (i2s->reg->DAO & (I2S_DAO_DAI_STOP | I2S_DAO_MUTE | I2S_DAO_DAI_WS_SEL));
  1162. if (master == 0U) {reg_daoi |= I2S_DAO_DAI_WS_SEL;}
  1163. i2s->reg->DAO = reg_daoi;
  1164. } else {
  1165. i2s->info->rx.data_bits = data_bits;
  1166. i2s->info->rx.master = master;
  1167. i2s->reg->RXRATE = reg_rate;
  1168. i2s->reg->RXBITRATE = reg_bitrate;
  1169. i2s->reg->RXMODE = reg_mode;
  1170. reg_daoi |= (i2s->reg->DAI & (I2S_DAO_DAI_STOP | I2S_DAO_DAI_WS_SEL));
  1171. if (master == 0U) {reg_daoi |= I2S_DAO_DAI_WS_SEL;}
  1172. i2s->reg->DAI = reg_daoi;
  1173. }
  1174. i2s->info->flags |= I2S_FLAG_CONFIGURED;
  1175. return ARM_DRIVER_OK;
  1176. }
  1177. /**
  1178. \fn ARM_SAI_STATUS I2S_GetStatus (I2S_RESOURCES *i2s)
  1179. \brief Get I2S status.
  1180. \param[in] i2s Pointer to I2S resources
  1181. \return SAI status \ref ARM_SAI_STATUS
  1182. */
  1183. static ARM_SAI_STATUS I2S_GetStatus (I2S_RESOURCES *i2s) {
  1184. ARM_SAI_STATUS status;
  1185. status.frame_error = i2s->info->status.frame_error;
  1186. status.rx_busy = i2s->info->status.rx_busy;
  1187. status.rx_overflow = i2s->info->status.rx_overflow;
  1188. status.tx_busy = i2s->info->status.tx_busy;
  1189. status.tx_underflow = i2s->info->status.tx_underflow;
  1190. return status;
  1191. }
  1192. /**
  1193. \fn void I2S_IRQHandler (I2S_RESOURCES *i2s)
  1194. \brief I2S Interrupt handler.
  1195. \param[in] i2s Pointer to I2S resources
  1196. */
  1197. static void I2S_IRQHandler (I2S_RESOURCES *i2s) {
  1198. uint32_t state, val, event, level;
  1199. uint32_t i, j;
  1200. uint8_t *ptr_buf;
  1201. state = i2s->reg->STATE;
  1202. event = 0U;
  1203. if (state & I2S_STATE_IRQ) {
  1204. // Fill TX FIFO if needed
  1205. if (i2s->reg->IRQ & I2S_IRQ_TX_IRQ_ENABLE) {
  1206. // Check for TX underflow
  1207. if (i2s->info->tx.num == 0U) {
  1208. // Set TX underflow event and flag
  1209. i2s->info->status.tx_underflow = 1U;
  1210. event |= ARM_SAI_EVENT_TX_UNDERFLOW;
  1211. // Disable TX interrupt
  1212. i2s->reg->IRQ &= ~I2S_IRQ_TX_IRQ_ENABLE;
  1213. } else {
  1214. // Get TX level
  1215. level = ((i2s->reg->STATE & I2S_STATE_TX_LEVEL_MSK) >> I2S_STATE_TX_LEVEL_POS);
  1216. if (level == 8U) { level = 0U; }
  1217. else { level = 7U - level; }
  1218. while (((i2s->info->tx.cnt + 4U) <= i2s->info->tx.num) && (level != 0U)) {
  1219. // Copy all available 32bit data to FIFO, until FIFO is full
  1220. ptr_buf = i2s->info->tx.buf + i2s->info->tx.cnt;
  1221. i2s->reg->TXFIFO = *(__packed uint32_t *)(ptr_buf);
  1222. // Update TX buffer info
  1223. i2s->info->tx.cnt += 4U;
  1224. level--;
  1225. }
  1226. if ((i2s->info->tx.cnt < i2s->info->tx.num) && (level != 0U)) {
  1227. while (i2s->info->tx.cnt < i2s->info->tx.num) {
  1228. // Copy remaining data to residue buffer (data < 32bits)
  1229. i2s->info->tx.residue_buf[i2s->info->tx.residue_cnt++] = i2s->info->tx.buf[i2s->info->tx.cnt++];
  1230. }
  1231. }
  1232. if (i2s->info->tx.cnt == i2s->info->tx.num) {
  1233. i2s->info->status.tx_busy = 0U;
  1234. i2s->info->tx.num = 0U;
  1235. event |= ARM_SAI_EVENT_SEND_COMPLETE;
  1236. // Set FIFO level to 0, to detect TX underflow
  1237. val = i2s->reg->IRQ & ~I2S_IRQ_TX_DEPTH_IRQ_MSK;
  1238. i2s->reg->IRQ = val;
  1239. }
  1240. }
  1241. }
  1242. // RX interrupt
  1243. if (i2s->reg->IRQ & I2S_IRQ_RX_IRQ_ENABLE) {
  1244. // Check for RX overflow
  1245. if (i2s->info->rx.num == 0U) {
  1246. // Flush residue buffer
  1247. i2s->info->rx.residue_cnt = 0U;
  1248. i2s->info->rx.residue_num = 0U;
  1249. i2s->info->status.rx_overflow = 1U;
  1250. event |= ARM_SAI_EVENT_RX_OVERFLOW;
  1251. i2s->reg->IRQ &= ~I2S_IRQ_RX_IRQ_ENABLE;
  1252. } else {
  1253. // Get FIFO level
  1254. level = (i2s->reg->STATE & I2S_STATE_RX_LEVEL_MSK) >> I2S_STATE_RX_LEVEL_POS;
  1255. while (((i2s->info->rx.cnt + 4U) <= i2s->info->rx.num) && (level != 0U)) {
  1256. // Read FIFO
  1257. ptr_buf = i2s->info->rx.buf + i2s->info->rx.cnt;
  1258. *(__packed uint32_t *)(ptr_buf) = i2s->reg->RXFIFO;
  1259. i2s->info->rx.cnt += 4U;
  1260. level--;
  1261. }
  1262. if ((i2s->info->rx.cnt < i2s->info->rx.num) && (level != 0U)) {
  1263. // Read FIFO
  1264. val = i2s->reg->RXFIFO;
  1265. j = 0U;
  1266. for (i = 0U; i < 4U; i++) {
  1267. if ((i2s->info->rx.cnt < i2s->info->rx.num)) {
  1268. i2s->info->rx.buf[i2s->info->rx.cnt++] = (uint8_t)(val >> j);
  1269. } else {
  1270. i2s->info->rx.residue_buf[i2s->info->rx.residue_num++] = (uint8_t)(val >> j);
  1271. }
  1272. j += 8U;
  1273. }
  1274. }
  1275. if (i2s->info->rx.cnt == i2s->info->rx.num) {
  1276. i2s->info->status.rx_busy = 0U;
  1277. i2s->info->rx.num = 0U;
  1278. event |= ARM_SAI_EVENT_RECEIVE_COMPLETE;
  1279. // Set FIFO level to full, to detect RX overflow
  1280. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1281. val |= (8U << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1282. i2s->reg->IRQ = val;
  1283. }
  1284. }
  1285. }
  1286. }
  1287. if ((event != 0U) && (i2s->info->cb_event != NULL)) {
  1288. i2s->info->cb_event (event);
  1289. }
  1290. }
  1291. #if (((RTE_I2S0 != 0U) &&(RTE_I2S0_DMA_TX_EN == 1U)) || \
  1292. ((RTE_I2S1 != 0U) &&(RTE_I2S1_DMA_TX_EN == 1U)))
  1293. static void I2S_GPDMA_Tx_Event (uint32_t event, I2S_RESOURCES *i2s) {
  1294. uint32_t evt = 0;
  1295. switch (event) {
  1296. case GPDMA_EVENT_TERMINAL_COUNT_REQUEST:
  1297. // Update TX buffer info
  1298. i2s->info->tx.cnt += (i2s->info->tx.num / 4U) * 4U;
  1299. while (i2s->info->tx.cnt < i2s->info->tx.num) {
  1300. // Copy remaining data to residue buffer (data < 32bits)
  1301. i2s->info->tx.residue_buf[i2s->info->tx.residue_cnt++] = i2s->info->tx.buf[i2s->info->tx.cnt++];
  1302. }
  1303. // Clear TX busy flag
  1304. i2s->info->status.tx_busy = 0U;
  1305. // Clear TX num and enable TX interrupt to detect TX underflow
  1306. i2s->info->tx.num = 0U;
  1307. i2s->reg->IRQ |= I2S_IRQ_TX_IRQ_ENABLE;
  1308. // Set Send complete event
  1309. evt = ARM_SAI_EVENT_SEND_COMPLETE;
  1310. break;
  1311. case GPDMA_EVENT_ERROR:
  1312. break;
  1313. }
  1314. if ((evt != 0U) && (i2s->info->cb_event != NULL)) {
  1315. i2s->info->cb_event (evt);
  1316. }
  1317. }
  1318. #endif
  1319. #if (((RTE_I2S0 != 0U) &&(RTE_I2S0_DMA_RX_EN == 1U)) || \
  1320. ((RTE_I2S1 != 0U) &&(RTE_I2S1_DMA_RX_EN == 1U)))
  1321. static void I2S_GPDMA_Rx_Event (uint32_t event, I2S_RESOURCES *i2s) {
  1322. uint32_t evt = 0U;
  1323. uint32_t val;
  1324. switch (event) {
  1325. case GPDMA_EVENT_TERMINAL_COUNT_REQUEST:
  1326. if (i2s->info->rx.cnt == i2s->info->rx.num) {
  1327. // Clear RX busy flag
  1328. i2s->info->status.rx_busy = 0U;
  1329. // Set receive complete event
  1330. evt = ARM_SAI_EVENT_RECEIVE_COMPLETE;
  1331. // Set FIFO level to full, to detect RX overflow
  1332. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1333. val |= (8U << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1334. i2s->reg->IRQ = val;
  1335. } else {
  1336. // Set user defined level, to retrieve remaining requested data
  1337. val = i2s->reg->IRQ & ~I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1338. val |= (i2s->rx_fifo_level << I2S_IRQ_RX_DEPTH_IRQ_POS) & I2S_IRQ_RX_DEPTH_IRQ_MSK;
  1339. i2s->reg->IRQ = val;
  1340. }
  1341. i2s->reg->IRQ |= I2S_IRQ_RX_IRQ_ENABLE;
  1342. break;
  1343. case GPDMA_EVENT_ERROR:
  1344. break;
  1345. }
  1346. if ((evt != 0U) && (i2s->info->cb_event != NULL)) {
  1347. i2s->info->cb_event (evt);
  1348. }
  1349. }
  1350. #endif
  1351. #if (RTE_I2S0)
  1352. // I2S0 Driver Wrapper functions
  1353. static ARM_SAI_CAPABILITIES I2S0_GetCapabilities (void) {
  1354. return I2S_GetCapabilities (&I2S0_Resources);
  1355. }
  1356. static int32_t I2S0_Initialize (ARM_SAI_SignalEvent_t cb_event) {
  1357. return I2S_Initialize (cb_event, &I2S0_Resources);
  1358. }
  1359. static int32_t I2S0_Uninitialize (void) {
  1360. return I2S_Uninitialize (&I2S0_Resources);
  1361. }
  1362. static int32_t I2S0_PowerControl (ARM_POWER_STATE state) {
  1363. return I2S_PowerControl (state, &I2S0_Resources);
  1364. }
  1365. static int32_t I2S0_Send (const void *data, uint32_t num) {
  1366. return I2S_Send (data, num, &I2S0_Resources);
  1367. }
  1368. static int32_t I2S0_Receive (void *data, uint32_t num) {
  1369. return I2S_Receive (data, num, &I2S0_Resources);
  1370. }
  1371. static uint32_t I2S0_GetTxCount (void) {
  1372. return I2S_GetTxCount (&I2S0_Resources);
  1373. }
  1374. static uint32_t I2S0_GetRxCount (void) {
  1375. return I2S_GetRxCount (&I2S0_Resources);
  1376. }
  1377. static int32_t I2S0_Control (uint32_t control, uint32_t arg1, uint32_t arg2) {
  1378. return I2S_Control (control, arg1, arg2, &I2S0_Resources);
  1379. }
  1380. static ARM_SAI_STATUS I2S0_GetStatus (void) {
  1381. return I2S_GetStatus (&I2S0_Resources);
  1382. }
  1383. void I2S0_IRQHandler (void) {
  1384. I2S_IRQHandler (&I2S0_Resources);
  1385. }
  1386. #if (RTE_I2S0_DMA_TX_EN == 1)
  1387. void I2S0_GPDMA_Tx_Event (uint32_t event) {
  1388. I2S_GPDMA_Tx_Event (event, &I2S0_Resources);
  1389. }
  1390. #endif
  1391. #if (RTE_I2S0_DMA_RX_EN == 1)
  1392. void I2S0_GPDMA_Rx_Event (uint32_t event) {
  1393. I2S_GPDMA_Rx_Event (event, &I2S0_Resources);
  1394. }
  1395. #endif
  1396. // SAI0 Driver Control Block
  1397. ARM_DRIVER_SAI Driver_SAI0 = {
  1398. I2Sx_GetVersion,
  1399. I2S0_GetCapabilities,
  1400. I2S0_Initialize,
  1401. I2S0_Uninitialize,
  1402. I2S0_PowerControl,
  1403. I2S0_Send,
  1404. I2S0_Receive,
  1405. I2S0_GetTxCount,
  1406. I2S0_GetRxCount,
  1407. I2S0_Control,
  1408. I2S0_GetStatus
  1409. };
  1410. #endif
  1411. #if (RTE_I2S1)
  1412. // I2S1 Driver Wrapper functions
  1413. static ARM_SAI_CAPABILITIES I2S1_GetCapabilities (void) {
  1414. return I2S_GetCapabilities (&I2S1_Resources);
  1415. }
  1416. static int32_t I2S1_Initialize (ARM_SAI_SignalEvent_t cb_event) {
  1417. return I2S_Initialize (cb_event, &I2S1_Resources);
  1418. }
  1419. static int32_t I2S1_Uninitialize (void) {
  1420. return I2S_Uninitialize (&I2S1_Resources);
  1421. }
  1422. static int32_t I2S1_PowerControl (ARM_POWER_STATE state) {
  1423. return I2S_PowerControl (state, &I2S1_Resources);
  1424. }
  1425. static int32_t I2S1_Send (const void *data, uint32_t num) {
  1426. return I2S_Send (data, num, &I2S1_Resources);
  1427. }
  1428. static int32_t I2S1_Receive (void *data, uint32_t num) {
  1429. return I2S_Receive (data, num, &I2S1_Resources);
  1430. }
  1431. static uint32_t I2S1_GetTxCount (void) {
  1432. return I2S_GetTxCount (&I2S1_Resources);
  1433. }
  1434. static uint32_t I2S1_GetRxCount (void) {
  1435. return I2S_GetRxCount (&I2S1_Resources);
  1436. }
  1437. static int32_t I2S1_Control (uint32_t control, uint32_t arg1, uint32_t arg2) {
  1438. return I2S_Control (control, arg1, arg2, &I2S1_Resources);
  1439. }
  1440. static ARM_SAI_STATUS I2S1_GetStatus (void) {
  1441. return I2S_GetStatus (&I2S1_Resources);
  1442. }
  1443. void I2S1_IRQHandler (void) {
  1444. I2S_IRQHandler (&I2S1_Resources);
  1445. }
  1446. #if (RTE_I2S1_DMA_TX_EN == 1)
  1447. void I2S1_GPDMA_Tx_Event (uint32_t event) {
  1448. I2S_GPDMA_Tx_Event (event, &I2S1_Resources);
  1449. }
  1450. #endif
  1451. #if (RTE_I2S1_DMA_RX_EN == 1)
  1452. void I2S1_GPDMA_Rx_Event (uint32_t event) {
  1453. I2S_GPDMA_Rx_Event (event, &I2S1_Resources);
  1454. }
  1455. #endif
  1456. // SAI1 Driver Control Block
  1457. ARM_DRIVER_SAI Driver_SAI1 = {
  1458. I2Sx_GetVersion,
  1459. I2S1_GetCapabilities,
  1460. I2S1_Initialize,
  1461. I2S1_Uninitialize,
  1462. I2S1_PowerControl,
  1463. I2S1_Send,
  1464. I2S1_Receive,
  1465. I2S1_GetTxCount,
  1466. I2S1_GetRxCount,
  1467. I2S1_Control,
  1468. I2S1_GetStatus
  1469. };
  1470. #endif