fsl_asrc.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*
  2. * Copyright 2019-2021 NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include "fsl_asrc.h"
  8. /* Component ID definition, used by tools. */
  9. #ifndef FSL_COMPONENT_ID
  10. #define FSL_COMPONENT_ID "platform.drivers.asrc"
  11. #endif
  12. /*******************************************************************************
  13. * Definitations
  14. ******************************************************************************/
  15. /*! @brief Typedef for asrc tx interrupt handler. */
  16. typedef void (*asrc_isr_t)(ASRC_Type *base, asrc_handle_t *asrcHandle);
  17. /*! @brief ASRC support maximum channel number */
  18. #define ASRC_SUPPORT_MAXIMUM_CHANNEL_NUMER (10U)
  19. #define ASRC_SAMPLE_RATIO_DECIMAL_DEPTH (26U)
  20. /*******************************************************************************
  21. * Prototypes
  22. ******************************************************************************/
  23. /*!
  24. * @brief ASRC read non blocking.
  25. *
  26. * @param base ASRC base pointer.
  27. * @param channelPair ASRC channel pair.
  28. * @param destAddress dest buffer address.
  29. * @param samples number of samples to read.
  30. * @param sampleWidth the width that one sample takes.
  31. */
  32. static void ASRC_ReadNonBlocking(
  33. ASRC_Type *base, asrc_channel_pair_t channelPair, uint32_t *destAddress, uint32_t samples, uint32_t sampleWidth);
  34. /*!
  35. * @brief ASRC write non blocking.
  36. *
  37. * @param base ASRC base pointer.
  38. * @param channelPair ASRC channel pair.
  39. * @param srcAddress source buffer address.
  40. * @param samples number of samples to read.
  41. * @param sampleMask the mask of sample data.
  42. * @param sampleWidth the width that one sample takes.
  43. */
  44. static void ASRC_WriteNonBlocking(ASRC_Type *base,
  45. asrc_channel_pair_t channelPair,
  46. const uint32_t *srcAddress,
  47. uint32_t samples,
  48. uint32_t sampleMask,
  49. uint32_t sampleWidth);
  50. /*!
  51. * @brief ASRC calculate divider and prescaler.
  52. *
  53. * @param sampleRate_Hz sample rate.
  54. * @param sourceClock_Hz source clock.
  55. */
  56. static uint32_t ASRC_CalculateClockDivider(uint32_t sampleRate_Hz, uint32_t sourceClock_Hz);
  57. /*!
  58. * @brief ASRC pre/post processing selection.
  59. *
  60. * @param inSampleRate in audio data sample rate.
  61. * @param outSampleRate out audio data sample rate.
  62. * @param preProc pre processing selection.
  63. * @param postProc post precessing selection.
  64. */
  65. static status_t ASRC_ProcessSelection(uint32_t inSampleRate,
  66. uint32_t outSampleRate,
  67. uint32_t *preProc,
  68. uint32_t *postProc);
  69. /*******************************************************************************
  70. * Variables
  71. ******************************************************************************/
  72. /* Base pointer array */
  73. static ASRC_Type *const s_asrcBases[] = ASRC_BASE_PTRS;
  74. /*!@brief asrc handle pointer */
  75. static asrc_handle_t *s_asrcHandle[ARRAY_SIZE(s_asrcBases)][FSL_ASRC_CHANNEL_PAIR_COUNT];
  76. /* IRQ number array */
  77. static const IRQn_Type s_asrcIRQ[] = ASRC_IRQS;
  78. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  79. /* Clock name array */
  80. static const clock_ip_name_t s_asrcClock[] = ASRC_CLOCKS;
  81. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  82. /*! @brief Pointer to IRQ handler for each instance. */
  83. static asrc_isr_t s_asrcIsr;
  84. /*******************************************************************************
  85. * Code
  86. ******************************************************************************/
  87. uint32_t ASRC_GetInstance(ASRC_Type *base)
  88. {
  89. uint32_t instance;
  90. /* Find the instance index from base address mappings. */
  91. for (instance = 0; instance < ARRAY_SIZE(s_asrcBases); instance++)
  92. {
  93. if (s_asrcBases[instance] == base)
  94. {
  95. break;
  96. }
  97. }
  98. assert(instance < ARRAY_SIZE(s_asrcBases));
  99. return instance;
  100. }
  101. static void ASRC_ReadNonBlocking(
  102. ASRC_Type *base, asrc_channel_pair_t channelPair, uint32_t *destAddress, uint32_t samples, uint32_t sampleWidth)
  103. {
  104. uint32_t i = 0U;
  105. uint32_t *destAddr = destAddress;
  106. volatile uint32_t *srcAddr = ASRC_ASRDO_ADDR(base, channelPair);
  107. for (i = 0U; i < samples; i++)
  108. {
  109. *destAddr = *srcAddr;
  110. destAddr = (uint32_t *)((uint32_t)destAddr + sampleWidth);
  111. }
  112. }
  113. static void ASRC_WriteNonBlocking(ASRC_Type *base,
  114. asrc_channel_pair_t channelPair,
  115. const uint32_t *srcAddress,
  116. uint32_t samples,
  117. uint32_t sampleMask,
  118. uint32_t sampleWidth)
  119. {
  120. uint32_t i = 0U;
  121. const uint32_t *srcAddr = srcAddress;
  122. volatile uint32_t *destAddr = ASRC_ASRDI_ADDR(base, channelPair);
  123. for (i = 0U; i < samples; i++)
  124. {
  125. *destAddr = *srcAddr & sampleMask;
  126. srcAddr = (uint32_t *)((uint32_t)srcAddr + sampleWidth);
  127. }
  128. }
  129. static uint32_t ASRC_CalculateClockDivider(uint32_t sampleRate_Hz, uint32_t sourceClock_Hz)
  130. {
  131. assert(sourceClock_Hz >= sampleRate_Hz);
  132. uint32_t divider = sourceClock_Hz / sampleRate_Hz;
  133. uint32_t prescaler = 0U;
  134. /* sourceClock_Hz = sampleRate_Hz * divider * (2 ^ prescaler) */
  135. while (divider > 8U)
  136. {
  137. divider >>= 1U;
  138. prescaler++;
  139. }
  140. /* Hardware limitation:
  141. * If the prescaler is set to 1, the clock divider can only be set to 1 and the clock source must have a 50% duty
  142. * cycle
  143. */
  144. if ((prescaler == 1U) && (divider != 1U))
  145. {
  146. divider >>= 1U;
  147. prescaler++;
  148. }
  149. /* fine tuning */
  150. if (sourceClock_Hz / ((1UL << prescaler) * divider) > sampleRate_Hz)
  151. {
  152. divider++;
  153. }
  154. return ((divider - 1U) << 3U) | (prescaler & 0x7U);
  155. }
  156. static status_t ASRC_ProcessSelection(uint32_t inSampleRate,
  157. uint32_t outSampleRate,
  158. uint32_t *preProc,
  159. uint32_t *postProc)
  160. {
  161. bool op2Cond = false;
  162. bool op0Cond = false;
  163. op2Cond = (((inSampleRate * 15U > outSampleRate * 16U) && (outSampleRate < 56000U)) ||
  164. ((inSampleRate > 56000U) && (outSampleRate < 56000U)));
  165. op0Cond = (inSampleRate * 23U < outSampleRate * 8U);
  166. /* preProc == 4 or preProc == 5 is not support now */
  167. if ((inSampleRate * 8U > 129U * outSampleRate) || ((inSampleRate * 8U > 65U * outSampleRate)))
  168. {
  169. return kStatus_ASRCNotSupport;
  170. }
  171. if (inSampleRate * 8U > 33U * outSampleRate)
  172. {
  173. *preProc = 2U;
  174. }
  175. else if (inSampleRate * 8U > 15U * outSampleRate)
  176. {
  177. if (inSampleRate > 152000U)
  178. {
  179. *preProc = 2U;
  180. }
  181. else
  182. {
  183. *preProc = 1U;
  184. }
  185. }
  186. else if (inSampleRate < 76000U)
  187. {
  188. *preProc = 0;
  189. }
  190. else if (inSampleRate > 152000U)
  191. {
  192. *preProc = 2;
  193. }
  194. else
  195. {
  196. *preProc = 1;
  197. }
  198. if (op2Cond)
  199. {
  200. *postProc = 2;
  201. }
  202. else if (op0Cond)
  203. {
  204. *postProc = 0;
  205. }
  206. else
  207. {
  208. *postProc = 1;
  209. }
  210. return kStatus_Success;
  211. }
  212. /*!
  213. * brief Map register sample width to real sample width.
  214. *
  215. * note This API is depends on the ASRC configuration, should be called after the ASRC_SetChannelPairConfig.
  216. * param base asrc base pointer.
  217. * param channelPair asrc channel pair index.
  218. * param inWidth ASRC channel pair number.
  219. * param outWidth input sample rate.
  220. * retval input sample mask value.
  221. */
  222. uint32_t ASRC_MapSamplesWidth(ASRC_Type *base, asrc_channel_pair_t channelPair, uint32_t *inWidth, uint32_t *outWidth)
  223. {
  224. uint32_t sampleMask = 0U,
  225. inRegWidth = (ASRC_ASRMCR1(base, channelPair) & ASRC_ASRMCR1_IWD_MASK) >> ASRC_ASRMCR1_IWD_SHIFT,
  226. outRegWidth = ASRC_ASRMCR1(base, channelPair) & ASRC_ASRMCR1_OW16_MASK,
  227. inDataAlign = (ASRC_ASRMCR1(base, channelPair) & ASRC_ASRMCR1_IMSB_MASK) >> ASRC_ASRMCR1_IMSB_SHIFT,
  228. outDataAlign = (ASRC_ASRMCR1(base, channelPair) & ASRC_ASRMCR1_OMSB_MASK) >> ASRC_ASRMCR1_OMSB_SHIFT;
  229. /* get in sample width */
  230. if (inRegWidth == (uint32_t)kASRC_DataWidth8Bit)
  231. {
  232. *inWidth = 1U;
  233. sampleMask = 0xFFU;
  234. if (inDataAlign == (uint32_t)kASRC_DataAlignMSB)
  235. {
  236. *inWidth = 2U;
  237. sampleMask = 0xFF00U;
  238. }
  239. }
  240. else if (inRegWidth == (uint32_t)kASRC_DataWidth16Bit)
  241. {
  242. *inWidth = 2U;
  243. sampleMask = 0xFFFFU;
  244. if (inDataAlign == (uint32_t)kASRC_DataAlignMSB)
  245. {
  246. *inWidth = 4U;
  247. sampleMask = 0xFFFF0000U;
  248. }
  249. }
  250. else
  251. {
  252. *inWidth = 3U;
  253. sampleMask = 0xFFFFFFU;
  254. if (inDataAlign == (uint32_t)kASRC_DataAlignMSB)
  255. {
  256. sampleMask = 0xFFFFFF00U;
  257. *inWidth = 4U;
  258. }
  259. }
  260. /* get out sample width */
  261. if (outRegWidth == (uint32_t)kASRC_DataWidth16Bit)
  262. {
  263. *outWidth = 2U;
  264. if (outDataAlign == (uint32_t)kASRC_DataAlignMSB)
  265. {
  266. *outWidth = 4U;
  267. }
  268. }
  269. else
  270. {
  271. *outWidth = 4U;
  272. }
  273. return sampleMask;
  274. }
  275. /*!
  276. * brief ASRC configure ideal ratio.
  277. * The ideal ratio should be used when input clock source is not avalible.
  278. *
  279. * param base ASRC base pointer.
  280. * param channelPair ASRC channel pair.
  281. * param inputSampleRate input audio data sample rate.
  282. * param outputSampleRate output audio data sample rate.
  283. */
  284. status_t ASRC_SetIdealRatioConfig(ASRC_Type *base,
  285. asrc_channel_pair_t channelPair,
  286. uint32_t inputSampleRate,
  287. uint32_t outputSampleRate)
  288. {
  289. uint32_t ratio = 0U, i = 0U;
  290. uint32_t preProc = 0U, postProc = 0U;
  291. uint32_t asrcfg = base->ASRCFG;
  292. /* caculate integer part */
  293. ratio = (inputSampleRate / outputSampleRate) << ASRC_SAMPLE_RATIO_DECIMAL_DEPTH;
  294. inputSampleRate %= outputSampleRate;
  295. /* get decimal part */
  296. for (i = 1U; i <= ASRC_SAMPLE_RATIO_DECIMAL_DEPTH; i++)
  297. {
  298. inputSampleRate <<= 1;
  299. if (inputSampleRate < outputSampleRate)
  300. {
  301. continue;
  302. }
  303. ratio |= 1UL << (ASRC_SAMPLE_RATIO_DECIMAL_DEPTH - i);
  304. inputSampleRate -= outputSampleRate;
  305. if (0U == inputSampleRate)
  306. {
  307. break;
  308. }
  309. }
  310. /* select pre/post precessing option */
  311. if (ASRC_ProcessSelection(inputSampleRate, outputSampleRate, &preProc, &postProc) != kStatus_Success)
  312. {
  313. return kStatus_ASRCNotSupport;
  314. }
  315. ASRC_IDEAL_RATIO_HIGH(base, channelPair) = ASRC_ASRIDRHA_IDRATIOA_H(ratio >> 24U);
  316. ASRC_IDEAL_RATIO_LOW(base, channelPair) = ASRC_ASRIDRLA_IDRATIOA_L(ratio);
  317. base->ASRCTR &= ~ASRC_ASRCTR_AT_MASK(channelPair);
  318. asrcfg &= ~(ASRC_ASRCFG_PRE_MODE_MASK(channelPair) | ASRC_ASRCFG_POST_MODE_MASK(channelPair));
  319. asrcfg |= ASRC_ASRCFG_PRE_MODE(preProc, channelPair) | ASRC_ASRCFG_POST_MODE(postProc, channelPair);
  320. base->ASRCFG = asrcfg;
  321. return kStatus_Success;
  322. }
  323. /*!
  324. * brief Initializes the asrc peripheral.
  325. *
  326. * This API gates the asrc clock. The asrc module can't operate unless ASRC_Init is called to enable the clock.
  327. *
  328. * param base asrc base pointer.
  329. * param asrcPeripheralClock_Hz peripheral clock of ASRC.
  330. */
  331. void ASRC_Init(ASRC_Type *base, uint32_t asrcPeripheralClock_Hz)
  332. {
  333. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  334. /* Enable the asrc clock */
  335. CLOCK_EnableClock(s_asrcClock[ASRC_GetInstance(base)]);
  336. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  337. /* disable ASRC channel pair, enable ASRC */
  338. base->ASRCTR = 1U;
  339. /* disable all the interrupt */
  340. base->ASRIER = 0U;
  341. #if (defined FSL_FEATURE_ASRC_PARAMETER_REGISTER_NAME_ASRPM) && FSL_FEATURE_ASRC_PARAMETER_REGISTER_NAME_ASRPM
  342. /* set paramter register to default configurations per recommand value in reference manual */
  343. base->ASRPM[0] = 0x7fffffU;
  344. base->ASRPM[1] = 0x255555U;
  345. base->ASRPM[2] = 0xff7280U;
  346. base->ASRPM[3] = 0xff7280U;
  347. base->ASRPM[4] = 0xff7280U;
  348. #else
  349. /* set paramter register to default configurations per recommand value in reference manual */
  350. base->ASRPMn[0] = 0x7fffffU;
  351. base->ASRPMn[1] = 0x255555U;
  352. base->ASRPMn[2] = 0xff7280U;
  353. base->ASRPMn[3] = 0xff7280U;
  354. base->ASRPMn[4] = 0xff7280U;
  355. #endif /*FSL_FEATURE_ASRC_PARAMETER_REGISTER_NAME_ASRPM*/
  356. /* set task queue fifo */
  357. base->ASRTFR1 = ASRC_ASRTFR1_TF_BASE(0x7C);
  358. /* 76K/56K divider */
  359. base->ASR76K = ASRC_ASR76K_ASR76K(asrcPeripheralClock_Hz / 76000U);
  360. base->ASR56K = ASRC_ASR56K_ASR56K(asrcPeripheralClock_Hz / 56000U);
  361. }
  362. /*!
  363. * brief De-initializes the ASRC peripheral.
  364. *
  365. * This API gates the ASRC clock and disable ASRC module. The ASRC module can't operate unless ASRC_Init
  366. *
  367. * param base ASRC base pointer.
  368. */
  369. void ASRC_Deinit(ASRC_Type *base)
  370. {
  371. /* disable ASRC module */
  372. ASRC_ModuleEnable(base, false);
  373. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  374. CLOCK_DisableClock(s_asrcClock[ASRC_GetInstance(base)]);
  375. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  376. }
  377. /*!
  378. * brief Do software reset .
  379. *
  380. * This software reset bit is self-clear bit, it will generate a software reset signal inside ASRC.
  381. * After 9 cycles of the ASRC processing clock, this reset process will stop and this bit will cleared
  382. * automatically.
  383. *
  384. * param base ASRC base pointer
  385. */
  386. void ASRC_SoftwareReset(ASRC_Type *base)
  387. {
  388. base->ASRCTR |= ASRC_ASRCTR_SRST_MASK;
  389. /* polling reset clear automatically */
  390. while ((base->ASRCTR & ASRC_ASRCTR_SRST_MASK) != 0U)
  391. {
  392. }
  393. }
  394. /*!
  395. * brief ASRC configure channel pair.
  396. *
  397. * param base ASRC base pointer.
  398. * param channelPair index of channel pair, reference _asrc_channel_pair.
  399. * param config ASRC channel pair configuration pointer.
  400. * param inputSampleRate in audio data sample rate.
  401. * param outSampleRate out audio data sample rate.
  402. */
  403. status_t ASRC_SetChannelPairConfig(ASRC_Type *base,
  404. asrc_channel_pair_t channelPair,
  405. asrc_channel_pair_config_t *config,
  406. uint32_t inputSampleRate,
  407. uint32_t outputSampleRate)
  408. {
  409. assert(config != NULL);
  410. if (config->outDataWidth == kASRC_DataWidth8Bit)
  411. {
  412. return kStatus_InvalidArgument;
  413. }
  414. if (((inputSampleRate < (uint32_t)kASRC_SampleRate_8000HZ) ||
  415. (inputSampleRate > (uint32_t)kASRC_SampleRate_192000HZ)) ||
  416. ((outputSampleRate < (uint32_t)kASRC_SampleRate_8000HZ) ||
  417. (outputSampleRate > (uint32_t)kASRC_SampleRate_192000HZ)) ||
  418. (((outputSampleRate > (uint32_t)kASRC_SampleRate_8000HZ) &&
  419. (outputSampleRate < (uint32_t)kASRC_SampleRate_30000HZ)) &&
  420. (inputSampleRate / outputSampleRate > 8U || outputSampleRate / inputSampleRate > 24U)))
  421. {
  422. return kStatus_InvalidArgument;
  423. }
  424. uint32_t i = 0U;
  425. /* channel pair processing selection and ratio configuration */
  426. uint32_t asrctr = base->ASRCTR & (~(ASRC_ASRCTR_AT_MASK(channelPair) | ASRC_ASRCTR_RATIO_MASK(channelPair)));
  427. /* use automatic selection for processing option by default */
  428. asrctr |= ASRC_ASRCTR_AT_MASK(channelPair);
  429. /* ratio configuration */
  430. asrctr |= ASRC_ASRCTR_RATIO(config->sampleRateRatio, channelPair);
  431. base->ASRCTR = asrctr;
  432. /* audio data channel counter configurations */
  433. uint32_t asrcncr = base->ASRCNCR & (~ASRC_ASRCNCR_CHANNEL_COUNTER_MASK(channelPair));
  434. base->ASRCNCR = asrcncr | ASRC_ASRCNCR_CHANNEL_COUNTER(config->audioDataChannels, channelPair);
  435. /* in clock source and out clock source configurations */
  436. uint32_t asrcsr =
  437. base->ASRCSR &
  438. (~(ASRC_ASRCSR_INPUT_CLOCK_SOURCE_MASK(channelPair) | ASRC_ASRCSR_OUTPUT_CLOCK_SOURCE_MASK(channelPair)));
  439. asrcsr |= ASRC_ASRCSR_OUTPUT_CLOCK_SOURCE(config->outClockSource, channelPair);
  440. if (config->inClockSource != kASRC_ClockSourceNotAvalible)
  441. {
  442. asrcsr |= ASRC_ASRCSR_INPUT_CLOCK_SOURCE(config->inClockSource, channelPair);
  443. }
  444. base->ASRCSR = asrcsr;
  445. /* clock divider configuration */
  446. uint32_t asrcdr =
  447. base->ASRCDR1 &
  448. (~(ASRC_ASRCDR_INPUT_PRESCALER_MASK(channelPair) | ASRC_ASRCDR_INPUT_DIVIDER_MASK(channelPair) |
  449. ASRC_ASRCDR_OUTPUT_PRESCALER_MASK(channelPair) | ASRC_ASRCDR_OUTPUT_DIVIDER_MASK(channelPair)));
  450. asrcdr |= ASCR_ASRCDR_OUTPUT_CLOCK_DIVIDER_PRESCALER(
  451. ASRC_CalculateClockDivider(outputSampleRate, config->outSourceClock_Hz), channelPair);
  452. if (config->inClockSource != kASRC_ClockSourceNotAvalible)
  453. {
  454. asrcdr |= ASCR_ASRCDR_INPUT_CLOCK_DIVIDER_PRESCALER(
  455. ASRC_CalculateClockDivider(inputSampleRate, config->inSourceClock_Hz), channelPair);
  456. }
  457. if (channelPair == kASRC_ChannelPairC)
  458. {
  459. base->ASRCDR2 = asrcdr;
  460. }
  461. else
  462. {
  463. base->ASRCDR1 = asrcdr;
  464. }
  465. /* data width/sign extension/data align configuration */
  466. ASRC_ASRMCR1(base, channelPair) = ASRC_ASRMCR1_OW16(config->outDataWidth) | ASRC_ASRMCR1_IWD(config->inDataWidth) |
  467. ASRC_ASRMCR1_OSGN(config->outSignExtension) |
  468. ASRC_ASRMCR1_OMSB(config->outDataAlign) | ASRC_ASRMCR1_IMSB(config->inDataAlign);
  469. /* data configurations, MISC */
  470. uint32_t asrmcra = ASRC_ASRMCR(base, channelPair) &
  471. (~(ASRC_ASRMCRA_BUFSTALLA_MASK | ASRC_ASRMCRA_EXTTHRSHA_MASK |
  472. ASRC_ASRMCRA_INFIFO_THRESHOLDA_MASK | ASRC_ASRMCRA_OUTFIFO_THRESHOLDA_MASK));
  473. /* buffer stall */
  474. asrmcra |= ASRC_ASRMCRA_BUFSTALLA(config->bufStallWhenFifoEmptyFull);
  475. /* in fifo and out fifo threshold */
  476. asrmcra |= ASRC_ASRMCRA_EXTTHRSHA_MASK | ASRC_ASRMCRA_INFIFO_THRESHOLDA(config->inFifoThreshold - 1UL) |
  477. ASRC_ASRMCRA_OUTFIFO_THRESHOLDA(config->outFifoThreshold - 1UL);
  478. ASRC_ASRMCR(base, channelPair) = asrmcra;
  479. if (config->sampleRateRatio == kASRC_RatioUseIdealRatio)
  480. {
  481. if (ASRC_SetIdealRatioConfig(base, channelPair, inputSampleRate, outputSampleRate) != kStatus_Success)
  482. {
  483. return kStatus_ASRCChannelPairConfigureFailed;
  484. }
  485. }
  486. /* channel pair enable */
  487. ASRC_ChannelPairEnable(base, channelPair, true);
  488. /* wait channel initial served */
  489. while (!ASRC_GetChannelPairInitialStatus(base, channelPair))
  490. {
  491. }
  492. for (i = 0U; i < (uint32_t)config->audioDataChannels * 4U; i++)
  493. {
  494. ASRC_ChannelPairWriteData(base, channelPair, 0U);
  495. }
  496. return kStatus_Success;
  497. }
  498. /*!
  499. * brief Get output sample buffer size.
  500. *
  501. * note This API is depends on the ASRC output configuration, should be called after the ASRC_SetChannelPairConfig.
  502. *
  503. * param base asrc base pointer.
  504. * param channelPair ASRC channel pair number.
  505. * param inSampleRate input sample rate.
  506. * param outSampleRate output sample rate.
  507. * param inSamples input sampleS size.
  508. * retval output buffer size in byte.
  509. */
  510. uint32_t ASRC_GetOutSamplesSize(ASRC_Type *base,
  511. asrc_channel_pair_t channelPair,
  512. uint32_t inSampleRate,
  513. uint32_t outSampleRate,
  514. uint32_t inSamplesize)
  515. {
  516. uint32_t inSamples = 0U;
  517. uint32_t outSamples = 0U;
  518. uint32_t outSamplesBufSize = 0U, audioChannels = ASRC_GET_CHANNEL_COUNTER(base, channelPair);
  519. ;
  520. asrc_data_width_t outWdith = (base->ASRMCR1[channelPair] & ASRC_ASRMCR1_OW16_MASK) == ASRC_ASRMCR1_OW16_MASK ?
  521. kASRC_DataWidth16Bit :
  522. kASRC_DataWidth24Bit;
  523. asrc_data_align_t outAlign = (base->ASRMCR1[channelPair] & ASRC_ASRMCR1_OMSB_MASK) == ASRC_ASRMCR1_OMSB_MASK ?
  524. kASRC_DataAlignMSB :
  525. kASRC_DataAlignLSB;
  526. uint32_t inWdith = (base->ASRMCR1[channelPair] & ASRC_ASRMCR1_IWD_MASK) >> ASRC_ASRMCR1_IWD_SHIFT;
  527. asrc_data_align_t inAlign = (base->ASRMCR1[channelPair] & ASRC_ASRMCR1_IMSB_MASK) == ASRC_ASRMCR1_IMSB_MASK ?
  528. kASRC_DataAlignMSB :
  529. kASRC_DataAlignLSB;
  530. bool signExtend = (base->ASRMCR1[channelPair] & ASRC_ASRMCR1_OSGN_MASK) == ASRC_ASRMCR1_OSGN_MASK ? true : false;
  531. /* 24bit input data */
  532. if (inWdith == 0U)
  533. {
  534. inSamples = inSamplesize / (inAlign == kASRC_DataAlignMSB ? 4U : 3U);
  535. }
  536. /* 16bit input data */
  537. else if (inWdith == 1U)
  538. {
  539. inSamples = inSamplesize / (inAlign == kASRC_DataAlignMSB ? 4U : 2U);
  540. }
  541. /* 8bit input data */
  542. else
  543. {
  544. inSamples = inSamplesize / (inAlign == kASRC_DataAlignMSB ? 2U : 1U);
  545. }
  546. outSamples = (uint32_t)((uint64_t)inSamples * outSampleRate / inSampleRate);
  547. /* make sure output samples is in group */
  548. outSamples = outSamples - outSamples % audioChannels;
  549. if (outWdith == kASRC_DataWidth16Bit)
  550. {
  551. if ((outAlign == kASRC_DataAlignMSB) || signExtend)
  552. {
  553. outSamplesBufSize = outSamples * 4U;
  554. }
  555. else
  556. {
  557. outSamplesBufSize = outSamples * 2U;
  558. }
  559. }
  560. if (outWdith == kASRC_DataWidth24Bit)
  561. {
  562. outSamplesBufSize = outSamples * 4U;
  563. }
  564. return outSamplesBufSize;
  565. }
  566. /*!
  567. * brief Performs an blocking convert on asrc.
  568. *
  569. * note This API returns immediately after the convert finished.
  570. *
  571. * param base asrc base pointer.
  572. * param channelPair channel pair index.
  573. * param xfer Pointer to the ASRC_transfer_t structure.
  574. * retval kStatus_Success Successfully started the data receive.
  575. */
  576. status_t ASRC_TransferBlocking(ASRC_Type *base, asrc_channel_pair_t channelPair, asrc_transfer_t *xfer)
  577. {
  578. assert(xfer != NULL);
  579. uint32_t inWaterMark = ASRC_ASRMCR(base, channelPair) & ASRC_ASRMCRA_INFIFO_THRESHOLDA_MASK,
  580. outWaterMark = (ASRC_ASRMCR(base, channelPair) & ASRC_ASRMCRA_OUTFIFO_THRESHOLDA_MASK) >>
  581. ASRC_ASRMCRA_OUTFIFO_THRESHOLDA_SHIFT,
  582. audioChannels = ASRC_GET_CHANNEL_COUNTER(base, channelPair);
  583. uint8_t *inAddr = (uint8_t *)xfer->inData, *outAddr = (uint8_t *)xfer->outData;
  584. uint32_t onceWriteSamples = 0U;
  585. uint32_t status = 0U, inSampleMask = 0U, inSamples = 0U, outSamples = 0U, inWidth = 0U, outWidth = 0U;
  586. inSampleMask = ASRC_MapSamplesWidth(base, channelPair, &inWidth, &outWidth);
  587. inSamples = xfer->inDataSize / inWidth;
  588. outSamples = xfer->outDataSize / outWidth;
  589. inWaterMark *= audioChannels;
  590. outWaterMark *= audioChannels;
  591. while (outSamples != 0U)
  592. {
  593. status = ASRC_GetStatus(base);
  594. if ((status & ((uint32_t)kASRC_StatusPairCInputReady | (uint32_t)kASRC_StatusPairBInputReady |
  595. (uint32_t)kASRC_StatusPairAInputReady)) != 0U)
  596. {
  597. onceWriteSamples =
  598. MIN(inSamples, (size_t)((FSL_ASRC_CHANNEL_PAIR_FIFO_DEPTH * audioChannels - inWaterMark)));
  599. ASRC_WriteNonBlocking(base, channelPair, (uint32_t *)(uint32_t)inAddr, onceWriteSamples, inSampleMask,
  600. inWidth);
  601. inAddr = (uint8_t *)((uint32_t)inAddr + onceWriteSamples * inWidth);
  602. inSamples -= onceWriteSamples;
  603. }
  604. if (outSamples > outWaterMark)
  605. {
  606. if ((status & ((uint32_t)kASRC_StatusPairCOutputReady | (uint32_t)kASRC_StatusPairAOutputReady |
  607. (uint32_t)kASRC_StatusPairBOutputReady)) != 0U)
  608. {
  609. ASRC_ReadNonBlocking(base, channelPair, (uint32_t *)(uint32_t)outAddr, outWaterMark, outWidth);
  610. outAddr = (uint8_t *)((uint32_t)outAddr + outWaterMark * outWidth);
  611. outSamples -= outWaterMark;
  612. }
  613. }
  614. else
  615. {
  616. outSamples -=
  617. ASRC_GetRemainFifoSamples(base, channelPair, (uint32_t *)(uint32_t)outAddr, outWidth, outSamples);
  618. continue;
  619. }
  620. }
  621. return kStatus_Success;
  622. }
  623. /*!
  624. * brief ASRC configure channel pair.
  625. *
  626. * param base ASRC base pointer.
  627. * param handle ASRC transactional handle pointer.
  628. * param config ASRC channel pair configuration pointer.
  629. * param inputSampleRate in audio data sample rate.
  630. * param outputSampleRate out audio data sample rate.
  631. */
  632. status_t ASRC_TransferSetChannelPairConfig(ASRC_Type *base,
  633. asrc_handle_t *handle,
  634. asrc_channel_pair_config_t *config,
  635. uint32_t inputSampleRate,
  636. uint32_t outputSampleRate)
  637. {
  638. assert(handle != NULL);
  639. handle->in.fifoThreshold = config->inFifoThreshold * (uint32_t)config->audioDataChannels;
  640. handle->out.fifoThreshold = config->outFifoThreshold * (uint32_t)config->audioDataChannels;
  641. handle->audioDataChannels = config->audioDataChannels;
  642. if (ASRC_SetChannelPairConfig(base, handle->channelPair, config, inputSampleRate, outputSampleRate) !=
  643. kStatus_Success)
  644. {
  645. return kStatus_ASRCChannelPairConfigureFailed;
  646. }
  647. handle->in.sampleMask =
  648. ASRC_MapSamplesWidth(base, handle->channelPair, &handle->in.sampleWidth, &handle->out.sampleWidth);
  649. return kStatus_Success;
  650. }
  651. /*!
  652. * brief Get left samples in fifo.
  653. *
  654. * param base asrc base pointer.
  655. * param channelPair ASRC channel pair number.
  656. * param buffer input sample numbers.
  657. * param outSampleWidth output sample width.
  658. * param remainSamples output sample rate.
  659. * retval remain samples number.
  660. */
  661. uint32_t ASRC_GetRemainFifoSamples(
  662. ASRC_Type *base, asrc_channel_pair_t channelPair, uint32_t *buffer, uint32_t outSampleWidth, uint32_t remainSamples)
  663. {
  664. uint32_t remainSamplesInFifo = 0U;
  665. uint32_t audioChannels = ASRC_GET_CHANNEL_COUNTER(base, channelPair);
  666. remainSamplesInFifo =
  667. ((ASRC_ASRFST_ADDR(base, channelPair) & ASRC_ASRFSTA_OUTFIFO_FILLA_MASK) >> ASRC_ASRFSTA_OUTFIFO_FILLA_SHIFT) *
  668. audioChannels;
  669. if (remainSamples < remainSamplesInFifo)
  670. {
  671. remainSamplesInFifo = remainSamples;
  672. }
  673. ASRC_ReadNonBlocking(base, channelPair, (uint32_t *)buffer, remainSamplesInFifo, outSampleWidth);
  674. return remainSamplesInFifo;
  675. }
  676. /*!
  677. * brief Initializes the ASRC handle.
  678. *
  679. * This function initializes the handle for the ASRC transactional APIs. Call
  680. * this function once to get the handle initialized.
  681. *
  682. * param base ASRC base pointer
  683. * param handle ASRC handle pointer.
  684. * param inCallback Pointer to the user callback function.
  685. * param outCallback Pointer to the user callback function.
  686. * param userData User parameter passed to the callback function
  687. */
  688. void ASRC_TransferCreateHandle(ASRC_Type *base,
  689. asrc_handle_t *handle,
  690. asrc_channel_pair_t channelPair,
  691. asrc_transfer_callback_t inCallback,
  692. asrc_transfer_callback_t outCallback,
  693. void *userData)
  694. {
  695. assert(handle != NULL);
  696. uint32_t instance = ASRC_GetInstance(base);
  697. (void)memset(handle, 0, sizeof(*handle));
  698. s_asrcHandle[instance][channelPair] = handle;
  699. handle->in.callback = inCallback;
  700. handle->out.callback = outCallback;
  701. handle->userData = userData;
  702. handle->channelPair = channelPair;
  703. /* Set the isr pointer */
  704. s_asrcIsr = ASRC_TransferHandleIRQ;
  705. (void)EnableIRQ(s_asrcIRQ[instance]);
  706. }
  707. /*!
  708. * brief Performs an interrupt non-blocking convert on asrc.
  709. *
  710. * note This API returns immediately after the transfer initiates, application should check the wait and check the
  711. * callback status.
  712. *
  713. * param base asrc base pointer.
  714. * param handle Pointer to the asrc_handle_t structure which stores the transfer state.
  715. * param xfer Pointer to the ASRC_transfer_t structure.
  716. * retval kStatus_Success Successfully started the data receive.
  717. * retval kStatus_ASRCBusy Previous receive still not finished.
  718. */
  719. status_t ASRC_TransferNonBlocking(ASRC_Type *base, asrc_handle_t *handle, asrc_transfer_t *xfer)
  720. {
  721. assert(handle != NULL);
  722. assert(xfer != NULL);
  723. /* Check if the queue is full */
  724. if ((handle->in.asrcQueue[handle->in.queueUser] != NULL) || (handle->out.asrcQueue[handle->out.queueUser] != NULL))
  725. {
  726. return kStatus_ASRCBusy;
  727. }
  728. /* Add into queue */
  729. handle->in.transferSamples[handle->in.queueUser] = xfer->inDataSize / handle->in.sampleWidth;
  730. handle->in.asrcQueue[handle->in.queueUser] = xfer->inData;
  731. handle->in.queueUser = (handle->in.queueUser + 1U) % ASRC_XFER_QUEUE_SIZE;
  732. handle->out.asrcQueue[handle->out.queueUser] = xfer->outData;
  733. handle->out.transferSamples[handle->out.queueUser] = xfer->outDataSize / handle->out.sampleWidth;
  734. handle->out.queueUser = (handle->out.queueUser + 1U) % ASRC_XFER_QUEUE_SIZE;
  735. if (handle->state != (uint32_t)kStatus_ASRCBusy)
  736. {
  737. /* enable channel pair interrupt */
  738. ASRC_EnableInterrupt(base, ASRC_ASRIER_INPUT_INTERRUPT_MASK(handle->channelPair) |
  739. (uint32_t)kASRC_OverLoadInterruptMask |
  740. ASRC_ASRIER_OUTPUTPUT_INTERRUPT_MASK(handle->channelPair));
  741. }
  742. /* Set the state to busy */
  743. handle->state = kStatus_ASRCBusy;
  744. return kStatus_Success;
  745. }
  746. /*!
  747. * brief Gets a set byte count.
  748. *
  749. * param base asrc base pointer.
  750. * param handle Pointer to the ASRC_handle_t structure which stores the transfer state.
  751. * param count Bytes count sent.
  752. * retval kStatus_Success Succeed get the transfer count.
  753. * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
  754. */
  755. status_t ASRC_TransferGetConvertedCount(ASRC_Type *base, asrc_handle_t *handle, size_t *count)
  756. {
  757. assert(handle != NULL);
  758. status_t status = kStatus_Success;
  759. if (handle->state != (uint32_t)kStatus_ASRCBusy)
  760. {
  761. status = kStatus_ASRCIdle;
  762. }
  763. else
  764. {
  765. *count = handle->out.transferSamples[handle->out.queueDriver];
  766. }
  767. return status;
  768. }
  769. /*!
  770. * brief Aborts the current convert.
  771. *
  772. * note This API can be called any time when an interrupt non-blocking transfer initiates
  773. * to abort the transfer early.
  774. *
  775. * param base asrc base pointer.
  776. * param handle Pointer to the ASRC_handle_t structure which stores the transfer state.
  777. */
  778. void ASRC_TransferAbortConvert(ASRC_Type *base, asrc_handle_t *handle)
  779. {
  780. assert(handle != NULL);
  781. /* enable ASRC module */
  782. ASRC_ModuleEnable(base, false);
  783. handle->state = kStatus_ASRCIdle;
  784. handle->in.queueDriver = 0;
  785. handle->in.queueUser = 0;
  786. handle->out.queueDriver = 0;
  787. handle->out.queueUser = 0;
  788. }
  789. /*!
  790. * brief Terminate all asrc convert.
  791. *
  792. * This function will clear all transfer slots buffered in the asrc queue. If users only want to abort the
  793. * current transfer slot, please call ASRC_TransferAbortSend.
  794. *
  795. * param base asrc base pointer.
  796. * param handle asrc eDMA handle pointer.
  797. */
  798. void ASRC_TransferTerminateConvert(ASRC_Type *base, asrc_handle_t *handle)
  799. {
  800. assert(handle != NULL);
  801. /* Abort the current transfer */
  802. ASRC_TransferAbortConvert(base, handle);
  803. /* Clear all the internal information */
  804. (void)memset(handle->in.asrcQueue, 0, sizeof(handle->in.asrcQueue));
  805. (void)memset(handle->in.transferSamples, 0, sizeof(handle->in.transferSamples));
  806. (void)memset(handle->out.asrcQueue, 0, sizeof(handle->out.asrcQueue));
  807. (void)memset(handle->out.transferSamples, 0, sizeof(handle->out.transferSamples));
  808. }
  809. /*!
  810. * brief ASRC convert interrupt handler.
  811. *
  812. * param base asrc base pointer.
  813. * param handle Pointer to the asrc_handle_t structure.
  814. */
  815. void ASRC_TransferHandleIRQ(ASRC_Type *base, asrc_handle_t *handle)
  816. {
  817. assert(handle != NULL);
  818. uint32_t status = base->ASRSTR;
  819. /* Handle Error */
  820. if ((status & (uint32_t)kASRC_StatusInputError) != 0U)
  821. {
  822. /* Call the callback */
  823. if (handle->in.callback != NULL)
  824. {
  825. (handle->in.callback)(base, handle, kStatus_ASRCConvertError, handle->userData);
  826. }
  827. }
  828. if ((status & (uint32_t)kASRC_StatusOutputError) != 0U)
  829. {
  830. /* Call the callback */
  831. if (handle->out.callback != NULL)
  832. {
  833. (handle->out.callback)(base, handle, kStatus_ASRCConvertError, handle->userData);
  834. }
  835. }
  836. /* Handle transfer */
  837. if ((status & ((uint32_t)kASRC_StatusPairCOutputReady | (uint32_t)kASRC_StatusPairAOutputReady |
  838. (uint32_t)kASRC_StatusPairBOutputReady)) != 0U)
  839. {
  840. if (handle->out.transferSamples[handle->out.queueDriver] != 0U)
  841. {
  842. ASRC_ReadNonBlocking(base, handle->channelPair,
  843. (uint32_t *)(uint32_t)handle->out.asrcQueue[handle->out.queueDriver],
  844. handle->out.fifoThreshold, handle->out.sampleWidth);
  845. handle->out.transferSamples[handle->out.queueDriver] -= handle->out.fifoThreshold;
  846. handle->out.asrcQueue[handle->out.queueDriver] =
  847. (uint8_t *)((uint32_t)handle->out.asrcQueue[handle->out.queueDriver] +
  848. handle->out.fifoThreshold * handle->out.sampleWidth);
  849. }
  850. }
  851. if ((status & ((uint32_t)kASRC_StatusPairCInputReady | (uint32_t)kASRC_StatusPairBInputReady |
  852. (uint32_t)kASRC_StatusPairAInputReady)) != 0U)
  853. {
  854. /* Judge if the data need to transmit is less than space */
  855. uint32_t size = MIN((handle->in.transferSamples[handle->in.queueDriver]),
  856. (size_t)((FSL_ASRC_CHANNEL_PAIR_FIFO_DEPTH * (uint32_t)handle->audioDataChannels -
  857. handle->in.fifoThreshold)));
  858. ASRC_WriteNonBlocking(base, handle->channelPair,
  859. (uint32_t *)(uint32_t)handle->in.asrcQueue[handle->in.queueDriver], size,
  860. handle->in.sampleMask, handle->in.sampleWidth);
  861. handle->in.transferSamples[handle->in.queueDriver] -= size;
  862. handle->in.asrcQueue[handle->in.queueDriver] =
  863. (uint8_t *)((uint32_t)handle->in.asrcQueue[handle->in.queueDriver] + size * handle->in.sampleWidth);
  864. }
  865. /* If finished a block, call the callback function */
  866. if (handle->in.transferSamples[handle->in.queueDriver] == 0U)
  867. {
  868. handle->in.asrcQueue[handle->in.queueDriver] = NULL;
  869. handle->in.queueDriver = (handle->in.queueDriver + 1U) % ASRC_XFER_QUEUE_SIZE;
  870. if (handle->in.callback != NULL)
  871. {
  872. (handle->in.callback)(base, handle, kStatus_ASRCIdle, handle->userData);
  873. }
  874. }
  875. if (handle->out.transferSamples[handle->out.queueDriver] < (handle->out.fifoThreshold + 1U))
  876. {
  877. handle->out.transferSamples[handle->out.queueDriver] -= ASRC_GetRemainFifoSamples(
  878. base, handle->channelPair, (uint32_t *)(uint32_t)handle->out.asrcQueue[handle->out.queueDriver],
  879. handle->out.sampleWidth, handle->out.transferSamples[handle->out.queueDriver]);
  880. }
  881. if (handle->out.transferSamples[handle->out.queueDriver] == 0U)
  882. {
  883. handle->out.asrcQueue[handle->out.queueDriver] = NULL;
  884. handle->out.queueDriver = (handle->out.queueDriver + 1U) % ASRC_XFER_QUEUE_SIZE;
  885. if (handle->out.callback != NULL)
  886. {
  887. (handle->out.callback)(base, handle, kStatus_ASRCIdle, handle->userData);
  888. }
  889. }
  890. /* If all data finished, just stop the transfer */
  891. if (handle->out.asrcQueue[handle->out.queueDriver] == NULL)
  892. {
  893. ASRC_TransferAbortConvert(base, handle);
  894. }
  895. }
  896. #if defined ASRC
  897. void ASRC_DriverIRQHandler(void);
  898. void ASRC_DriverIRQHandler(void)
  899. {
  900. /* channel PAIR A interrupt handling*/
  901. if ((ASRC->ASRSTR & (uint32_t)kASRC_StatusPairAInterrupt) != 0U)
  902. {
  903. s_asrcIsr(ASRC, s_asrcHandle[0][0U]);
  904. }
  905. /* channel PAIR B interrupt handling*/
  906. if ((ASRC->ASRSTR & (uint32_t)kASRC_StatusPairBInterrupt) != 0U)
  907. {
  908. s_asrcIsr(ASRC, s_asrcHandle[0][1U]);
  909. }
  910. /* channel PAIR C interrupt handling*/
  911. if ((ASRC->ASRSTR & (uint32_t)kASRC_StatusPairCInterrupt) != 0U)
  912. {
  913. s_asrcIsr(ASRC, s_asrcHandle[0][2U]);
  914. }
  915. SDK_ISR_EXIT_BARRIER;
  916. }
  917. #endif /* ASRC */