i2s.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /**
  2. * \file
  3. *
  4. * \brief SAM I2S - Inter-IC Sound Controller
  5. *
  6. * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
  7. *
  8. * \asf_license_start
  9. *
  10. * \page License
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright notice,
  16. * this list of conditions and the following disclaimer.
  17. *
  18. * 2. Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. *
  22. * 3. The name of Atmel may not be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * 4. This software may only be redistributed and used in connection with an
  26. * Atmel microcontroller product.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  31. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  32. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  36. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * \asf_license_stop
  41. *
  42. */
  43. /*
  44. * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
  45. */
  46. #include "i2s.h"
  47. /**
  48. * \brief Initializes a hardware I<SUP>2</SUP>S module instance
  49. *
  50. * Enables the clock and initialize the I<SUP>2</SUP>S module.
  51. *
  52. * \param[in,out] module_inst Pointer to the software module instance struct
  53. * \param[in] hw Pointer to the TCC hardware module
  54. *
  55. * \return Status of the initialization procedure.
  56. *
  57. * \retval STATUS_OK The module was initialized successfully
  58. * \retval STATUS_BUSY Hardware module was busy when the
  59. * initialization procedure was attempted
  60. * \retval STATUS_ERR_DENIED Hardware module was already enabled
  61. */
  62. enum status_code i2s_init(
  63. struct i2s_module *const module_inst,
  64. I2s *hw)
  65. {
  66. Assert(module_inst);
  67. Assert(hw);
  68. /* Enable the user interface clock in the PM */
  69. system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_I2S);
  70. /* Status check */
  71. uint32_t ctrla;
  72. ctrla = module_inst->hw->CTRLA.reg;
  73. if (ctrla & I2S_CTRLA_ENABLE) {
  74. if (ctrla & (I2S_CTRLA_SEREN1 |
  75. I2S_CTRLA_SEREN0 | I2S_CTRLA_CKEN1 | I2S_CTRLA_CKEN0)) {
  76. return STATUS_BUSY;
  77. } else {
  78. return STATUS_ERR_DENIED;
  79. }
  80. }
  81. /* Initialize module */
  82. module_inst->hw = hw;
  83. /* Initialize serializers */
  84. #if I2S_CALLBACK_MODE == true
  85. int i, j;
  86. for (i = 0; i < 2; i ++) {
  87. for (j = 0; j < I2S_SERIALIZER_CALLBACK_N; j ++) {
  88. module_inst->serializer[i].callback[j] = NULL;
  89. }
  90. module_inst->serializer[i].registered_callback_mask = 0;
  91. module_inst->serializer[i].enabled_callback_mask = 0;
  92. module_inst->serializer[i].job_buffer = NULL;
  93. module_inst->serializer[i].job_status = STATUS_OK;
  94. module_inst->serializer[i].requested_words = 0;
  95. module_inst->serializer[i].transferred_words = 0;
  96. module_inst->serializer[i].mode = I2S_SERIALIZER_RECEIVE;
  97. module_inst->serializer[i].data_size = I2S_DATA_SIZE_32BIT;
  98. }
  99. _i2s_instances[0] = module_inst;
  100. system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_I2S);
  101. #endif
  102. return STATUS_OK;
  103. }
  104. /**
  105. * \brief Configure specified I<SUP>2</SUP>S clock unit
  106. *
  107. * Enables the clock and initialize the clock unit, based on the given
  108. * configurations.
  109. *
  110. * \param[in,out] module_inst Pointer to the software module instance struct
  111. * \param[in] clock_unit I<SUP>2</SUP>S clock unit to initialize and configure
  112. * \param[in] config Pointer to the I<SUP>2</SUP>S clock unit configuration
  113. * options struct
  114. *
  115. * \return Status of the configuration procedure.
  116. *
  117. * \retval STATUS_OK The module was initialized successfully
  118. * \retval STATUS_BUSY Hardware module was busy when the
  119. * configuration procedure was attempted
  120. * \retval STATUS_ERR_DENIED Hardware module was already enabled
  121. * \retval STATUS_ERR_INVALID_ARG Invalid divider value or
  122. * MCK direction setting conflict
  123. */
  124. enum status_code i2s_clock_unit_set_config(
  125. struct i2s_module *const module_inst,
  126. const enum i2s_clock_unit clock_unit,
  127. const struct i2s_clock_unit_config *config)
  128. {
  129. Assert(module_inst);
  130. Assert(module_inst->hw);
  131. Assert(clock_unit < I2S_CLOCK_UNIT_N);
  132. Assert(config);
  133. /* Status check */
  134. uint32_t ctrla, syncbusy;
  135. syncbusy = module_inst->hw->SYNCBUSY.reg;
  136. ctrla = module_inst->hw->CTRLA.reg;
  137. /* Busy ? */
  138. if (syncbusy & (I2S_SYNCBUSY_CKEN0 << clock_unit)) {
  139. return STATUS_BUSY;
  140. }
  141. /* Already enabled ? */
  142. if (ctrla & (I2S_CTRLA_CKEN0 << clock_unit)) {
  143. return STATUS_ERR_DENIED;
  144. }
  145. /* Parameter check */
  146. if (config->clock.mck_src && config->clock.mck_out_enable) {
  147. return STATUS_ERR_INVALID_ARG;
  148. }
  149. /* Initialize Clock Unit */
  150. uint32_t clkctrl =
  151. (config->clock.mck_out_invert ? I2S_CLKCTRL_MCKOUTINV : 0) |
  152. (config->clock.sck_out_invert ? I2S_CLKCTRL_SCKOUTINV : 0) |
  153. (config->frame.frame_sync.invert_out ? I2S_CLKCTRL_FSOUTINV : 0) |
  154. (config->clock.mck_out_enable ? I2S_CLKCTRL_MCKEN : 0) |
  155. (config->clock.mck_src ? I2S_CLKCTRL_MCKSEL : 0) |
  156. (config->clock.sck_src ? I2S_CLKCTRL_SCKSEL : 0) |
  157. (config->frame.frame_sync.invert_use ? I2S_CLKCTRL_FSINV : 0) |
  158. (config->frame.frame_sync.source ? I2S_CLKCTRL_FSSEL : 0) |
  159. (config->frame.data_delay ? I2S_CLKCTRL_BITDELAY : 0);
  160. uint8_t div_val = config->clock.mck_out_div;
  161. if ((div_val > 0x21) || (div_val == 0)) {
  162. return STATUS_ERR_INVALID_ARG;
  163. } else {
  164. div_val --;
  165. }
  166. clkctrl |= I2S_CLKCTRL_MCKOUTDIV(div_val);
  167. div_val = config->clock.sck_div;
  168. if ((div_val > 0x21) || (div_val == 0)) {
  169. return STATUS_ERR_INVALID_ARG;
  170. } else {
  171. div_val --;
  172. }
  173. clkctrl |= I2S_CLKCTRL_MCKDIV(div_val);
  174. uint8_t number_slots = config->frame.number_slots;
  175. if (number_slots > 8) {
  176. return STATUS_ERR_INVALID_ARG;
  177. } else if (number_slots > 0) {
  178. number_slots --;
  179. }
  180. clkctrl |=
  181. I2S_CLKCTRL_NBSLOTS(number_slots) |
  182. I2S_CLKCTRL_FSWIDTH(config->frame.frame_sync.width) |
  183. I2S_CLKCTRL_SLOTSIZE(config->frame.slot_size);
  184. /* Write clock unit configurations */
  185. module_inst->hw->CLKCTRL[clock_unit].reg = clkctrl;
  186. /* Select general clock source */
  187. const uint8_t i2s_gclk_ids[2] = {I2S_GCLK_ID_0, I2S_GCLK_ID_1};
  188. struct system_gclk_chan_config gclk_chan_config;
  189. system_gclk_chan_get_config_defaults(&gclk_chan_config);
  190. gclk_chan_config.source_generator = config->clock.gclk_src;
  191. system_gclk_chan_set_config(i2s_gclk_ids[clock_unit], &gclk_chan_config);
  192. system_gclk_chan_enable(i2s_gclk_ids[clock_unit]);
  193. /* Initialize pins */
  194. struct system_pinmux_config pin_config;
  195. system_pinmux_get_config_defaults(&pin_config);
  196. if (config->mck_pin.enable) {
  197. pin_config.mux_position = config->mck_pin.mux;
  198. system_pinmux_pin_set_config(config->mck_pin.gpio, &pin_config);
  199. }
  200. if (config->sck_pin.enable) {
  201. pin_config.mux_position = config->sck_pin.mux;
  202. system_pinmux_pin_set_config(config->sck_pin.gpio, &pin_config);
  203. }
  204. if (config->fs_pin.enable) {
  205. pin_config.mux_position = config->fs_pin.mux;
  206. system_pinmux_pin_set_config(config->fs_pin.gpio, &pin_config);
  207. }
  208. return STATUS_OK;
  209. }
  210. /**
  211. * \brief Configure specified I<SUP>2</SUP>S serializer
  212. *
  213. * Enables the clock and initialize the serializer, based on the given
  214. * configurations.
  215. *
  216. * \param[in,out] module_inst Pointer to the software module instance struct
  217. * \param[in] serializer I<SUP>2</SUP>S serializer to initialize and configure
  218. * \param[in] config Pointer to the I<SUP>2</SUP>S serializer configuration
  219. * options struct
  220. *
  221. * \return Status of the configuration procedure.
  222. *
  223. * \retval STATUS_OK The module was initialized successfully
  224. * \retval STATUS_BUSY Hardware module was busy when the
  225. * configuration procedure was attempted
  226. * \retval STATUS_ERR_DENIED Hardware module was already enabled
  227. */
  228. enum status_code i2s_serializer_set_config(
  229. struct i2s_module *const module_inst,
  230. const enum i2s_serializer serializer,
  231. const struct i2s_serializer_config *config)
  232. {
  233. Assert(module_inst);
  234. Assert(module_inst->hw);
  235. Assert(serializer < I2S_SERIALIZER_N);
  236. Assert(config);
  237. /* Status check */
  238. uint32_t ctrla, syncbusy;
  239. syncbusy = module_inst->hw->SYNCBUSY.reg;
  240. ctrla = module_inst->hw->CTRLA.reg;
  241. /* Busy ? */
  242. if (syncbusy & ((I2S_SYNCBUSY_SEREN0 | I2S_SYNCBUSY_DATA0) << serializer)) {
  243. return STATUS_BUSY;
  244. }
  245. /* Already enabled ? */
  246. if (ctrla & (I2S_CTRLA_CKEN0 << serializer)) {
  247. return STATUS_ERR_DENIED;
  248. }
  249. /* Initialize Serializer */
  250. uint32_t serctrl =
  251. (config->loop_back ? I2S_SERCTRL_RXLOOP : 0) |
  252. (config->dma_usage ? I2S_SERCTRL_DMA : 0) |
  253. (config->mono_mode ? I2S_SERCTRL_MONO : 0) |
  254. (config->disable_data_slot[7] ? I2S_SERCTRL_SLOTDIS7 : 0) |
  255. (config->disable_data_slot[6] ? I2S_SERCTRL_SLOTDIS6 : 0) |
  256. (config->disable_data_slot[5] ? I2S_SERCTRL_SLOTDIS5 : 0) |
  257. (config->disable_data_slot[4] ? I2S_SERCTRL_SLOTDIS4 : 0) |
  258. (config->disable_data_slot[3] ? I2S_SERCTRL_SLOTDIS3 : 0) |
  259. (config->disable_data_slot[2] ? I2S_SERCTRL_SLOTDIS2 : 0) |
  260. (config->disable_data_slot[1] ? I2S_SERCTRL_SLOTDIS1 : 0) |
  261. (config->disable_data_slot[0] ? I2S_SERCTRL_SLOTDIS0 : 0) |
  262. (config->transfer_lsb_first ? I2S_SERCTRL_BITREV : 0) |
  263. (config->data_adjust_left_in_word ? I2S_SERCTRL_WORDADJ : 0) |
  264. (config->data_adjust_left_in_slot ? I2S_SERCTRL_SLOTADJ : 0) |
  265. (config->data_padding ? I2S_SERCTRL_TXSAME : 0);
  266. if (config->clock_unit < I2S_CLOCK_UNIT_N) {
  267. serctrl |= (config->clock_unit ? I2S_SERCTRL_CLKSEL : 0);
  268. } else {
  269. return STATUS_ERR_INVALID_ARG;
  270. }
  271. serctrl |=
  272. I2S_SERCTRL_SERMODE(config->mode) |
  273. I2S_SERCTRL_TXDEFAULT(config->line_default_state) |
  274. I2S_SERCTRL_DATASIZE(config->data_size) |
  275. I2S_SERCTRL_EXTEND(config->bit_padding);
  276. /* Write Serializer configuration */
  277. module_inst->hw->SERCTRL[serializer].reg = serctrl;
  278. /* Initialize pins */
  279. struct system_pinmux_config pin_config;
  280. system_pinmux_get_config_defaults(&pin_config);
  281. if (config->data_pin.enable) {
  282. pin_config.mux_position = config->data_pin.mux;
  283. system_pinmux_pin_set_config(config->data_pin.gpio, &pin_config);
  284. }
  285. /* Save configure */
  286. module_inst->serializer[serializer].mode = config->mode;
  287. module_inst->serializer[serializer].data_size = config->data_size;
  288. return STATUS_OK;
  289. }
  290. /**
  291. * \brief Retrieves the current module status.
  292. *
  293. * Retrieves the status of the module, giving overall state information.
  294. *
  295. * \param[in] module_inst Pointer to the I<SUP>2</SUP>S software instance struct
  296. *
  297. * \return Bitmask of \c I2S_STATUS_* flags.
  298. *
  299. * \retval I2S_STATUS_SYNC_BUSY Module is busy synchronization
  300. * \retval I2S_STATUS_TRANSMIT_UNDERRUN(x) Serializer x (0~1) is underrun
  301. * \retval I2S_STATUS_TRANSMIT_READY(x) Serializer x (0~1) is ready to
  302. * transmit new data word
  303. * \retval I2S_STATUS_RECEIVE_OVERRUN(x) Serializer x (0~1) is overrun
  304. * \retval I2S_STATUS_RECEIVE_READY(x) Serializer x (0~1) has data ready to
  305. * read
  306. */
  307. uint32_t i2s_get_status(
  308. const struct i2s_module *const module_inst)
  309. {
  310. /* Sanity check arguments */
  311. Assert(module_inst);
  312. Assert(module_inst->hw);
  313. uint32_t intflag = module_inst->hw->INTFLAG.reg;
  314. uint32_t status;
  315. if (module_inst->hw->SYNCBUSY.reg) {
  316. status = I2S_STATUS_SYNC_BUSY;
  317. } else {
  318. status = 0;
  319. }
  320. if (intflag & I2S_INTFLAG_TXUR0) {
  321. status |= I2S_STATUS_TRANSMIT_UNDERRUN(0);
  322. }
  323. if (intflag & I2S_INTFLAG_TXUR1) {
  324. status |= I2S_STATUS_TRANSMIT_UNDERRUN(1);
  325. }
  326. if ((intflag & I2S_INTFLAG_TXRDY0) &&
  327. !module_inst->hw->SYNCBUSY.bit.DATA0) {
  328. status |= I2S_STATUS_TRANSMIT_READY(0);
  329. }
  330. if ((intflag & I2S_INTFLAG_TXRDY1) &&
  331. !module_inst->hw->SYNCBUSY.bit.DATA1) {
  332. status |= I2S_STATUS_TRANSMIT_READY(1);
  333. }
  334. if (intflag & I2S_INTFLAG_RXOR0) {
  335. status |= I2S_STATUS_RECEIVE_OVERRUN(0);
  336. }
  337. if (intflag & I2S_INTFLAG_RXOR1) {
  338. status |= I2S_STATUS_RECEIVE_OVERRUN(1);
  339. }
  340. if (intflag & I2S_INTFLAG_RXRDY0) {
  341. status |= I2S_STATUS_RECEIVE_READY(0);
  342. }
  343. if (intflag & I2S_INTFLAG_RXRDY1) {
  344. status |= I2S_STATUS_RECEIVE_READY(1);
  345. }
  346. return status;
  347. }
  348. /**
  349. * \brief Clears a module status flags.
  350. *
  351. * Clears the given status flags of the module.
  352. *
  353. * \param[in] module_inst Pointer to the I<SUP>2</SUP>S software instance struct
  354. * \param[in] status Bitmask of \c I2S_STATUS_* flags to clear
  355. */
  356. void i2s_clear_status(
  357. const struct i2s_module *const module_inst,
  358. uint32_t status)
  359. {
  360. /* Sanity check arguments */
  361. Assert(module_inst);
  362. Assert(module_inst->hw);
  363. uint32_t intflag = 0;
  364. if (status & I2S_STATUS_TRANSMIT_UNDERRUN(0)) {
  365. intflag = I2S_INTFLAG_TXUR0;
  366. }
  367. if (status & I2S_STATUS_TRANSMIT_UNDERRUN(1)) {
  368. intflag = I2S_INTFLAG_TXUR1;
  369. }
  370. if (status & I2S_STATUS_TRANSMIT_READY(0)) {
  371. intflag = I2S_INTFLAG_TXRDY0;
  372. }
  373. if (status & I2S_STATUS_TRANSMIT_READY(1)) {
  374. intflag = I2S_INTFLAG_TXRDY1;
  375. }
  376. if (status & I2S_STATUS_RECEIVE_OVERRUN(0)) {
  377. intflag = I2S_INTFLAG_RXOR0;
  378. }
  379. if (status & I2S_STATUS_RECEIVE_OVERRUN(1)) {
  380. intflag = I2S_INTFLAG_RXOR1;
  381. }
  382. if (status & I2S_STATUS_RECEIVE_READY(0)) {
  383. intflag = I2S_INTFLAG_RXRDY0;
  384. }
  385. if (status & I2S_STATUS_RECEIVE_READY(1)) {
  386. intflag = I2S_INTFLAG_RXRDY1;
  387. }
  388. module_inst->hw->INTFLAG.reg = intflag;
  389. }
  390. /**
  391. * \brief Enable interrupts on status set
  392. *
  393. * Enable the given status interrupt request from the I<SUP>2</SUP>S module.
  394. *
  395. * \param[in] module_inst Pointer to the I<SUP>2</SUP>S software instance struct
  396. * \param[in] status Status interrupts to enable
  397. *
  398. * \return Status of enable procedure.
  399. *
  400. * \retval STATUS_OK Interrupt is enabled successfully
  401. * \retval STATUS_ERR_INVALID_ARG Status with no interrupt is passed
  402. */
  403. enum status_code i2s_enable_status_interrupt(
  404. struct i2s_module *const module_inst,
  405. uint32_t status)
  406. {
  407. /* Sanity check arguments */
  408. Assert(module_inst);
  409. /* No sync busy interrupt */
  410. if (status & I2S_STATUS_SYNC_BUSY) {
  411. return STATUS_ERR_INVALID_ARG;
  412. }
  413. Assert(module_inst->hw);
  414. uint32_t intflag = 0;
  415. if (status & I2S_STATUS_TRANSMIT_UNDERRUN(0)) {
  416. intflag = I2S_INTFLAG_TXUR0;
  417. }
  418. if (status & I2S_STATUS_TRANSMIT_UNDERRUN(1)) {
  419. intflag = I2S_INTFLAG_TXUR1;
  420. }
  421. if (status & I2S_STATUS_TRANSMIT_READY(0)) {
  422. intflag = I2S_INTFLAG_TXRDY0;
  423. }
  424. if (status & I2S_STATUS_TRANSMIT_READY(1)) {
  425. intflag = I2S_INTFLAG_TXRDY1;
  426. }
  427. if (status & I2S_STATUS_RECEIVE_OVERRUN(0)) {
  428. intflag = I2S_INTFLAG_RXOR0;
  429. }
  430. if (status & I2S_STATUS_RECEIVE_OVERRUN(1)) {
  431. intflag = I2S_INTFLAG_RXOR1;
  432. }
  433. if (status & I2S_STATUS_RECEIVE_READY(0)) {
  434. intflag = I2S_INTFLAG_RXRDY0;
  435. }
  436. if (status & I2S_STATUS_RECEIVE_READY(1)) {
  437. intflag = I2S_INTFLAG_RXRDY1;
  438. }
  439. module_inst->hw->INTENSET.reg = intflag;
  440. return STATUS_OK;
  441. }
  442. /**
  443. * \brief Disable interrupts on status set
  444. *
  445. * Disable the given status interrupt request from the I<SUP>2</SUP>S module.
  446. *
  447. * \param[in] module_inst Pointer to the I<SUP>2</SUP>S software instance struct
  448. * \param[in] status Status interrupts to disable
  449. */
  450. void i2s_disable_status_interrupt(
  451. struct i2s_module *const module_inst,
  452. uint32_t status)
  453. {
  454. /* Sanity check arguments */
  455. Assert(module_inst);
  456. Assert(module_inst->hw);
  457. uint32_t intflag = 0;
  458. if (status & I2S_STATUS_TRANSMIT_UNDERRUN(0)) {
  459. intflag = I2S_INTFLAG_TXUR0;
  460. }
  461. if (status & I2S_STATUS_TRANSMIT_UNDERRUN(1)) {
  462. intflag = I2S_INTFLAG_TXUR1;
  463. }
  464. if (status & I2S_STATUS_TRANSMIT_READY(0)) {
  465. intflag = I2S_INTFLAG_TXRDY0;
  466. }
  467. if (status & I2S_STATUS_TRANSMIT_READY(1)) {
  468. intflag = I2S_INTFLAG_TXRDY1;
  469. }
  470. if (status & I2S_STATUS_RECEIVE_OVERRUN(0)) {
  471. intflag = I2S_INTFLAG_RXOR0;
  472. }
  473. if (status & I2S_STATUS_RECEIVE_OVERRUN(1)) {
  474. intflag = I2S_INTFLAG_RXOR1;
  475. }
  476. if (status & I2S_STATUS_RECEIVE_READY(0)) {
  477. intflag = I2S_INTFLAG_RXRDY0;
  478. }
  479. if (status & I2S_STATUS_RECEIVE_READY(1)) {
  480. intflag = I2S_INTFLAG_RXRDY1;
  481. }
  482. module_inst->hw->INTENCLR.reg = intflag;
  483. }
  484. /**
  485. * \brief Write buffer to the specified Serializer of I<SUP>2</SUP>S module
  486. *
  487. * \param[in] module_inst Pointer to the software module instance struct
  488. * \param[in] serializer The serializer to write to
  489. * \param[in] buffer The data buffer to write
  490. * \param[in] size Number of data words to write
  491. *
  492. * \return Status of the initialization procedure.
  493. *
  494. * \retval STATUS_OK The data was sent successfully
  495. * \retval STATUS_ERR_DENIED The module or serializer is disabled
  496. * \retval STATUS_ERR_INVALID_ARG An invalid buffer pointer was supplied
  497. */
  498. enum status_code i2s_serializer_write_buffer_wait(
  499. const struct i2s_module *const module_inst,
  500. enum i2s_serializer serializer,
  501. void *buffer, uint32_t size)
  502. {
  503. Assert(module_inst);
  504. Assert(module_inst->hw);
  505. Assert(serializer < I2S_SERIALIZER_N);
  506. Assert(buffer);
  507. if (size == 0) {
  508. return STATUS_OK;
  509. }
  510. uint8_t data_size = 1; /* number of bytes */
  511. struct i2s_serializer_module *data_module = (struct i2s_serializer_module *)
  512. &module_inst->serializer[serializer];
  513. /* Check buffer */
  514. switch(data_module->data_size) {
  515. case I2S_DATA_SIZE_32BIT:
  516. case I2S_DATA_SIZE_24BIT:
  517. case I2S_DATA_SIZE_20BIT:
  518. case I2S_DATA_SIZE_18BIT:
  519. if ((uint32_t)buffer & 0x3) {
  520. return STATUS_ERR_INVALID_ARG;
  521. }
  522. data_size = 4;
  523. break;
  524. case I2S_DATA_SIZE_16BIT:
  525. case I2S_DATA_SIZE_16BIT_COMPACT:
  526. if ((uint32_t)buffer & 0x1) {
  527. return STATUS_ERR_INVALID_ARG;
  528. }
  529. data_size = 2;
  530. break;
  531. default:
  532. break;
  533. }
  534. /* Check status */
  535. if (!(module_inst->hw->CTRLA.reg &
  536. (I2S_CTRLA_ENABLE | (I2S_CTRLA_SEREN0 << serializer)))) {
  537. return STATUS_ERR_DENIED;
  538. }
  539. /* Write */
  540. uint32_t i;
  541. uint32_t sync_bit = I2S_SYNCBUSY_DATA0 << serializer;
  542. uint32_t ready_bit = I2S_INTFLAG_TXRDY0 << serializer;
  543. if (4 == data_size) {
  544. uint32_t *p32 = (uint32_t*)buffer;
  545. for (i = 0; i < size; i ++) {
  546. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  547. /* Wait Tx ready */
  548. }
  549. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  550. /* Wait Sync */
  551. }
  552. module_inst->hw->DATA[serializer].reg = p32[i];
  553. module_inst->hw->INTFLAG.reg = ready_bit;
  554. }
  555. } else if (2 == data_size) {
  556. uint16_t *p16 = (uint16_t*)buffer;
  557. for (i = 0; i < size; i ++) {
  558. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  559. /* Wait Tx ready */
  560. }
  561. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  562. /* Wait Sync */
  563. }
  564. module_inst->hw->DATA[serializer].reg = p16[i];
  565. module_inst->hw->INTFLAG.reg = ready_bit;
  566. }
  567. } else {
  568. uint8_t *p8 = (uint8_t*)buffer;
  569. for (i = 0; i < size; i ++) {
  570. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  571. /* Wait Tx ready */
  572. }
  573. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  574. /* Wait Sync */
  575. }
  576. module_inst->hw->DATA[serializer].reg = p8[i];
  577. module_inst->hw->INTFLAG.reg = ready_bit;
  578. }
  579. }
  580. return STATUS_OK;
  581. }
  582. /**
  583. * \brief Read from the specified Serializer of I<SUP>2</SUP>S module to a buffer
  584. *
  585. * \param[in] module_inst Pointer to the software module instance struct
  586. * \param[in] serializer The serializer to write to
  587. * \param[in] buffer The buffer to fill read data (NULL to discard)
  588. * \param[in] size Number of data words to read
  589. *
  590. * \return Status of the initialization procedure.
  591. *
  592. * \retval STATUS_OK The data was sent successfully
  593. * \retval STATUS_ERR_DENIED The module or serializer is disabled
  594. * \retval STATUS_ERR_INVALID_ARG An invalid buffer pointer was supplied
  595. */
  596. enum status_code i2s_serializer_read_buffer_wait(
  597. const struct i2s_module *const module_inst,
  598. enum i2s_serializer serializer,
  599. void *buffer, uint32_t size)
  600. {
  601. Assert(module_inst);
  602. Assert(module_inst->hw);
  603. if (size == 0) {
  604. return STATUS_OK;
  605. }
  606. uint8_t data_size = 1; /* number of bytes */
  607. struct i2s_serializer_module *data_module = (struct i2s_serializer_module *)
  608. &module_inst->serializer[serializer];
  609. /* Check buffer */
  610. switch(data_module->data_size) {
  611. case I2S_DATA_SIZE_32BIT:
  612. case I2S_DATA_SIZE_24BIT:
  613. case I2S_DATA_SIZE_20BIT:
  614. case I2S_DATA_SIZE_18BIT:
  615. if ((uint32_t)buffer & 0x3) {
  616. return STATUS_ERR_INVALID_ARG;
  617. }
  618. data_size = 4;
  619. break;
  620. case I2S_DATA_SIZE_16BIT:
  621. case I2S_DATA_SIZE_16BIT_COMPACT:
  622. if ((uint32_t)buffer & 0x1) {
  623. return STATUS_ERR_INVALID_ARG;
  624. }
  625. data_size = 2;
  626. break;
  627. default:
  628. break;
  629. }
  630. /* Check status */
  631. if (!(module_inst->hw->CTRLA.reg &
  632. (I2S_CTRLA_ENABLE | (I2S_CTRLA_SEREN0 << serializer)))) {
  633. return STATUS_ERR_DENIED;
  634. }
  635. /* Read */
  636. uint32_t i;
  637. uint32_t sync_bit = I2S_SYNCBUSY_DATA0 << serializer;
  638. uint32_t ready_bit = I2S_INTFLAG_RXRDY0 << serializer;
  639. if (buffer == NULL) {
  640. for (i = 0; i < size; i ++) {
  641. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  642. /* Wait Rx ready */
  643. }
  644. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  645. /* Wait Sync */
  646. }
  647. module_inst->hw->DATA[serializer].reg;
  648. module_inst->hw->INTFLAG.reg = ready_bit;
  649. }
  650. }
  651. else if (4 == data_size) {
  652. uint32_t *p32 = (uint32_t*)buffer;
  653. for (i = 0; i < size; i ++) {
  654. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  655. /* Wait Rx ready */
  656. }
  657. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  658. /* Wait Sync */
  659. }
  660. p32[i] = module_inst->hw->DATA[serializer].reg;
  661. module_inst->hw->INTFLAG.reg = ready_bit;
  662. }
  663. } else if (2 == data_size) {
  664. uint16_t *p16 = (uint16_t*)buffer;
  665. for (i = 0; i < size; i ++) {
  666. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  667. /* Wait Rx ready */
  668. }
  669. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  670. /* Wait Sync */
  671. }
  672. p16[i] = module_inst->hw->DATA[serializer].reg;
  673. module_inst->hw->INTFLAG.reg = ready_bit;
  674. }
  675. } else {
  676. uint8_t *p8 = (uint8_t*)buffer;
  677. for (i = 0; i < size; i ++) {
  678. while(!(module_inst->hw->INTFLAG.reg & ready_bit)) {
  679. /* Wait Tx ready */
  680. }
  681. while(module_inst->hw->SYNCBUSY.reg & sync_bit) {
  682. /* Wait Sync */
  683. }
  684. p8[i] = module_inst->hw->DATA[serializer].reg;
  685. module_inst->hw->INTFLAG.reg = ready_bit;
  686. }
  687. }
  688. return STATUS_OK;
  689. }