fsl_lpuart.c 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712
  1. /*
  2. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_lpuart.h"
  31. /*******************************************************************************
  32. * Definitions
  33. ******************************************************************************/
  34. /* LPUART transfer state. */
  35. enum _lpuart_transfer_states
  36. {
  37. kLPUART_TxIdle, /*!< TX idle. */
  38. kLPUART_TxBusy, /*!< TX busy. */
  39. kLPUART_RxIdle, /*!< RX idle. */
  40. kLPUART_RxBusy /*!< RX busy. */
  41. };
  42. /* Typedef for interrupt handler. */
  43. typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle);
  44. /*******************************************************************************
  45. * Prototypes
  46. ******************************************************************************/
  47. /*!
  48. * @brief Get the LPUART instance from peripheral base address.
  49. *
  50. * @param base LPUART peripheral base address.
  51. * @return LPUART instance.
  52. */
  53. uint32_t LPUART_GetInstance(LPUART_Type *base);
  54. /*!
  55. * @brief Check whether the RX ring buffer is full.
  56. *
  57. * @userData handle LPUART handle pointer.
  58. * @retval true RX ring buffer is full.
  59. * @retval false RX ring buffer is not full.
  60. */
  61. static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle);
  62. /*!
  63. * @brief Write to TX register using non-blocking method.
  64. *
  65. * This function writes data to the TX register directly, upper layer must make
  66. * sure the TX register is empty or TX FIFO has empty room before calling this function.
  67. *
  68. * @note This function does not check whether all the data has been sent out to bus,
  69. * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is
  70. * finished.
  71. *
  72. * @param base LPUART peripheral base address.
  73. * @param data Start addresss of the data to write.
  74. * @param length Size of the buffer to be sent.
  75. */
  76. static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
  77. /*!
  78. * @brief Read RX register using non-blocking method.
  79. *
  80. * This function reads data from the TX register directly, upper layer must make
  81. * sure the RX register is full or TX FIFO has data before calling this function.
  82. *
  83. * @param base LPUART peripheral base address.
  84. * @param data Start addresss of the buffer to store the received data.
  85. * @param length Size of the buffer.
  86. */
  87. static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length);
  88. /*******************************************************************************
  89. * Variables
  90. ******************************************************************************/
  91. /* Array of LPUART peripheral base address. */
  92. static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS;
  93. /* Array of LPUART handle. */
  94. static lpuart_handle_t *s_lpuartHandle[ARRAY_SIZE(s_lpuartBases)];
  95. /* Array of LPUART IRQ number. */
  96. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  97. static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS;
  98. static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS;
  99. #else
  100. static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
  101. #endif
  102. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  103. /* Array of LPUART clock name. */
  104. static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
  105. #if defined(LPUART_PERIPH_CLOCKS)
  106. /* Array of LPUART functional clock name. */
  107. static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS;
  108. #endif
  109. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  110. /* LPUART ISR for transactional APIs. */
  111. static lpuart_isr_t s_lpuartIsr;
  112. /*******************************************************************************
  113. * Code
  114. ******************************************************************************/
  115. uint32_t LPUART_GetInstance(LPUART_Type *base)
  116. {
  117. uint32_t instance;
  118. /* Find the instance index from base address mappings. */
  119. for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++)
  120. {
  121. if (s_lpuartBases[instance] == base)
  122. {
  123. break;
  124. }
  125. }
  126. assert(instance < ARRAY_SIZE(s_lpuartBases));
  127. return instance;
  128. }
  129. size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle)
  130. {
  131. assert(handle);
  132. size_t size;
  133. if (handle->rxRingBufferTail > handle->rxRingBufferHead)
  134. {
  135. size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
  136. }
  137. else
  138. {
  139. size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
  140. }
  141. return size;
  142. }
  143. static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle)
  144. {
  145. assert(handle);
  146. bool full;
  147. if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U))
  148. {
  149. full = true;
  150. }
  151. else
  152. {
  153. full = false;
  154. }
  155. return full;
  156. }
  157. static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
  158. {
  159. assert(data);
  160. size_t i;
  161. /* The Non Blocking write data API assume user have ensured there is enough space in
  162. peripheral to write. */
  163. for (i = 0; i < length; i++)
  164. {
  165. base->DATA = data[i];
  166. }
  167. }
  168. static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length)
  169. {
  170. assert(data);
  171. size_t i;
  172. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  173. uint32_t ctrl = base->CTRL;
  174. bool isSevenDataBits =
  175. ((ctrl & LPUART_CTRL_M7_MASK) ||
  176. ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
  177. #endif
  178. /* The Non Blocking read data API assume user have ensured there is enough space in
  179. peripheral to write. */
  180. for (i = 0; i < length; i++)
  181. {
  182. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  183. if (isSevenDataBits)
  184. {
  185. data[i] = (base->DATA & 0x7F);
  186. }
  187. else
  188. {
  189. data[i] = base->DATA;
  190. }
  191. #else
  192. data[i] = base->DATA;
  193. #endif
  194. }
  195. }
  196. status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
  197. {
  198. assert(config);
  199. assert(config->baudRate_Bps);
  200. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  201. assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark);
  202. assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark);
  203. #endif
  204. uint32_t temp;
  205. uint16_t sbr, sbrTemp;
  206. uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
  207. /* This LPUART instantiation uses a slightly different baud rate calculation
  208. * The idea is to use the best OSR (over-sampling rate) possible
  209. * Note, OSR is typically hard-set to 16 in other LPUART instantiations
  210. * loop to find the best OSR value possible, one that generates minimum baudDiff
  211. * iterate through the rest of the supported values of OSR */
  212. baudDiff = config->baudRate_Bps;
  213. osr = 0;
  214. sbr = 0;
  215. for (osrTemp = 4; osrTemp <= 32; osrTemp++)
  216. {
  217. /* calculate the temporary sbr value */
  218. sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp));
  219. /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
  220. if (sbrTemp == 0)
  221. {
  222. sbrTemp = 1;
  223. }
  224. /* Calculate the baud rate based on the temporary OSR and SBR values */
  225. calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp));
  226. tempDiff = calculatedBaud - config->baudRate_Bps;
  227. /* Select the better value between srb and (sbr + 1) */
  228. if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)))))
  229. {
  230. tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)));
  231. sbrTemp++;
  232. }
  233. if (tempDiff <= baudDiff)
  234. {
  235. baudDiff = tempDiff;
  236. osr = osrTemp; /* update and store the best OSR value calculated */
  237. sbr = sbrTemp; /* update store the best SBR value calculated */
  238. }
  239. }
  240. /* Check to see if actual baud rate is within 3% of desired baud rate
  241. * based on the best calculate OSR value */
  242. if (baudDiff > ((config->baudRate_Bps / 100) * 3))
  243. {
  244. /* Unacceptable baud rate difference of more than 3%*/
  245. return kStatus_LPUART_BaudrateNotSupport;
  246. }
  247. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  248. uint32_t instance = LPUART_GetInstance(base);
  249. /* Enable lpuart clock */
  250. CLOCK_EnableClock(s_lpuartClock[instance]);
  251. #if defined(LPUART_PERIPH_CLOCKS)
  252. CLOCK_EnableClock(s_lpuartPeriphClocks[instance]);
  253. #endif
  254. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  255. #if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
  256. /*Reset all internal logic and registers, except the Global Register */
  257. LPUART_SoftwareReset(base);
  258. #else
  259. /* Disable LPUART TX RX before setting. */
  260. base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
  261. #endif
  262. temp = base->BAUD;
  263. /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
  264. * If so, then "BOTHEDGE" sampling must be turned on */
  265. if ((osr > 3) && (osr < 8))
  266. {
  267. temp |= LPUART_BAUD_BOTHEDGE_MASK;
  268. }
  269. /* program the osr value (bit value is one less than actual value) */
  270. temp &= ~LPUART_BAUD_OSR_MASK;
  271. temp |= LPUART_BAUD_OSR(osr - 1);
  272. /* write the sbr value to the BAUD registers */
  273. temp &= ~LPUART_BAUD_SBR_MASK;
  274. base->BAUD = temp | LPUART_BAUD_SBR(sbr);
  275. /* Set bit count and parity mode. */
  276. base->BAUD &= ~LPUART_BAUD_M10_MASK;
  277. temp = base->CTRL &
  278. ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
  279. LPUART_CTRL_IDLECFG_MASK);
  280. temp |=
  281. (uint8_t)config->parityMode | LPUART_CTRL_IDLECFG(config->rxIdleConfig) | LPUART_CTRL_ILT(config->rxIdleType);
  282. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  283. if (kLPUART_SevenDataBits == config->dataBitsCount)
  284. {
  285. if (kLPUART_ParityDisabled != config->parityMode)
  286. {
  287. temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */
  288. }
  289. else
  290. {
  291. temp |= LPUART_CTRL_M7_MASK;
  292. }
  293. }
  294. else
  295. #endif
  296. {
  297. if (kLPUART_ParityDisabled != config->parityMode)
  298. {
  299. temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */
  300. }
  301. }
  302. base->CTRL = temp;
  303. #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
  304. /* set stop bit per char */
  305. temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK;
  306. base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount);
  307. #endif
  308. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  309. /* Set tx/rx WATER watermark
  310. Note:
  311. Take care of the RX FIFO, RX interrupt request only assert when received bytes
  312. equal or more than RX water mark, there is potential issue if RX water
  313. mark larger than 1.
  314. For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
  315. 5 bytes are received. the last byte will be saved in FIFO but not trigger
  316. RX interrupt because the water mark is 2.
  317. */
  318. base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark);
  319. /* Enable tx/rx FIFO */
  320. base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK);
  321. /* Flush FIFO */
  322. base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK);
  323. #endif
  324. /* Clear all status flags */
  325. temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
  326. LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
  327. #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
  328. temp |= LPUART_STAT_LBKDIF_MASK;
  329. #endif
  330. #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
  331. temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
  332. #endif
  333. #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
  334. /* Set the CTS configuration/TX CTS source. */
  335. base->MODIR |= LPUART_MODIR_TXCTSC(config->txCtsConfig) | LPUART_MODIR_TXCTSSRC(config->txCtsSource);
  336. if (config->enableRxRTS)
  337. {
  338. /* Enable the receiver RTS(request-to-send) function. */
  339. base->MODIR |= LPUART_MODIR_RXRTSE_MASK;
  340. }
  341. if (config->enableTxCTS)
  342. {
  343. /* Enable the CTS(clear-to-send) function. */
  344. base->MODIR |= LPUART_MODIR_TXCTSE_MASK;
  345. }
  346. #endif
  347. /* Set data bits order. */
  348. if (config->isMsb)
  349. {
  350. temp |= LPUART_STAT_MSBF_MASK;
  351. }
  352. else
  353. {
  354. temp &= ~LPUART_STAT_MSBF_MASK;
  355. }
  356. base->STAT |= temp;
  357. /* Enable TX/RX base on configure structure. */
  358. temp = base->CTRL;
  359. if (config->enableTx)
  360. {
  361. temp |= LPUART_CTRL_TE_MASK;
  362. }
  363. if (config->enableRx)
  364. {
  365. temp |= LPUART_CTRL_RE_MASK;
  366. }
  367. base->CTRL = temp;
  368. return kStatus_Success;
  369. }
  370. void LPUART_Deinit(LPUART_Type *base)
  371. {
  372. uint32_t temp;
  373. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  374. /* Wait tx FIFO send out*/
  375. while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT))
  376. {
  377. }
  378. #endif
  379. /* Wait last char shoft out */
  380. while (0 == (base->STAT & LPUART_STAT_TC_MASK))
  381. {
  382. }
  383. /* Clear all status flags */
  384. temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
  385. LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
  386. #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
  387. temp |= LPUART_STAT_LBKDIF_MASK;
  388. #endif
  389. #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
  390. temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
  391. #endif
  392. base->STAT |= temp;
  393. /* Disable the module. */
  394. base->CTRL = 0;
  395. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  396. uint32_t instance = LPUART_GetInstance(base);
  397. /* Disable lpuart clock */
  398. CLOCK_DisableClock(s_lpuartClock[instance]);
  399. #if defined(LPUART_PERIPH_CLOCKS)
  400. CLOCK_DisableClock(s_lpuartPeriphClocks[instance]);
  401. #endif
  402. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  403. }
  404. void LPUART_GetDefaultConfig(lpuart_config_t *config)
  405. {
  406. assert(config);
  407. config->baudRate_Bps = 115200U;
  408. config->parityMode = kLPUART_ParityDisabled;
  409. config->dataBitsCount = kLPUART_EightDataBits;
  410. config->isMsb = false;
  411. #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
  412. config->stopBitCount = kLPUART_OneStopBit;
  413. #endif
  414. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  415. config->txFifoWatermark = 0;
  416. config->rxFifoWatermark = 0;
  417. #endif
  418. #if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT
  419. config->enableRxRTS = false;
  420. config->enableTxCTS = false;
  421. config->txCtsConfig = kLPUART_CtsSampleAtStart;
  422. config->txCtsSource = kLPUART_CtsSourcePin;
  423. #endif
  424. config->rxIdleType = kLPUART_IdleTypeStartBit;
  425. config->rxIdleConfig = kLPUART_IdleCharacter1;
  426. config->enableTx = false;
  427. config->enableRx = false;
  428. }
  429. status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
  430. {
  431. assert(baudRate_Bps);
  432. uint32_t temp, oldCtrl;
  433. uint16_t sbr, sbrTemp;
  434. uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
  435. /* This LPUART instantiation uses a slightly different baud rate calculation
  436. * The idea is to use the best OSR (over-sampling rate) possible
  437. * Note, OSR is typically hard-set to 16 in other LPUART instantiations
  438. * loop to find the best OSR value possible, one that generates minimum baudDiff
  439. * iterate through the rest of the supported values of OSR */
  440. baudDiff = baudRate_Bps;
  441. osr = 0;
  442. sbr = 0;
  443. for (osrTemp = 4; osrTemp <= 32; osrTemp++)
  444. {
  445. /* calculate the temporary sbr value */
  446. sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp));
  447. /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
  448. if (sbrTemp == 0)
  449. {
  450. sbrTemp = 1;
  451. }
  452. /* Calculate the baud rate based on the temporary OSR and SBR values */
  453. calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp));
  454. tempDiff = calculatedBaud - baudRate_Bps;
  455. /* Select the better value between srb and (sbr + 1) */
  456. if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)))))
  457. {
  458. tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)));
  459. sbrTemp++;
  460. }
  461. if (tempDiff <= baudDiff)
  462. {
  463. baudDiff = tempDiff;
  464. osr = osrTemp; /* update and store the best OSR value calculated */
  465. sbr = sbrTemp; /* update store the best SBR value calculated */
  466. }
  467. }
  468. /* Check to see if actual baud rate is within 3% of desired baud rate
  469. * based on the best calculate OSR value */
  470. if (baudDiff < ((baudRate_Bps / 100) * 3))
  471. {
  472. /* Store CTRL before disable Tx and Rx */
  473. oldCtrl = base->CTRL;
  474. /* Disable LPUART TX RX before setting. */
  475. base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
  476. temp = base->BAUD;
  477. /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
  478. * If so, then "BOTHEDGE" sampling must be turned on */
  479. if ((osr > 3) && (osr < 8))
  480. {
  481. temp |= LPUART_BAUD_BOTHEDGE_MASK;
  482. }
  483. /* program the osr value (bit value is one less than actual value) */
  484. temp &= ~LPUART_BAUD_OSR_MASK;
  485. temp |= LPUART_BAUD_OSR(osr - 1);
  486. /* write the sbr value to the BAUD registers */
  487. temp &= ~LPUART_BAUD_SBR_MASK;
  488. base->BAUD = temp | LPUART_BAUD_SBR(sbr);
  489. /* Restore CTRL. */
  490. base->CTRL = oldCtrl;
  491. return kStatus_Success;
  492. }
  493. else
  494. {
  495. /* Unacceptable baud rate difference of more than 3%*/
  496. return kStatus_LPUART_BaudrateNotSupport;
  497. }
  498. }
  499. void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)
  500. {
  501. base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
  502. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  503. base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) |
  504. ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
  505. #endif
  506. mask &= 0xFFFFFF00U;
  507. base->CTRL |= mask;
  508. }
  509. void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)
  510. {
  511. base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
  512. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  513. base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) &
  514. ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
  515. #endif
  516. mask &= 0xFFFFFF00U;
  517. base->CTRL &= ~mask;
  518. }
  519. uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base)
  520. {
  521. uint32_t temp;
  522. temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8;
  523. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  524. temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8;
  525. #endif
  526. temp |= (base->CTRL & 0xFF0C000);
  527. return temp;
  528. }
  529. uint32_t LPUART_GetStatusFlags(LPUART_Type *base)
  530. {
  531. uint32_t temp;
  532. temp = base->STAT;
  533. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  534. temp |= (base->FIFO &
  535. (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >>
  536. 16;
  537. #endif
  538. return temp;
  539. }
  540. status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask)
  541. {
  542. uint32_t temp;
  543. status_t status;
  544. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  545. temp = (uint32_t)base->FIFO;
  546. temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK));
  547. temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK);
  548. base->FIFO = temp;
  549. #endif
  550. temp = (uint32_t)base->STAT;
  551. #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
  552. temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK));
  553. temp |= mask & LPUART_STAT_LBKDIF_MASK;
  554. #endif
  555. temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
  556. LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK));
  557. temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
  558. LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
  559. #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
  560. temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK));
  561. temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK);
  562. #endif
  563. base->STAT = temp;
  564. /* If some flags still pending. */
  565. if (mask & LPUART_GetStatusFlags(base))
  566. {
  567. /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag,
  568. kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag,
  569. kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag,
  570. kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */
  571. status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */
  572. }
  573. else
  574. {
  575. status = kStatus_Success;
  576. }
  577. return status;
  578. }
  579. void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
  580. {
  581. assert(data);
  582. /* This API can only ensure that the data is written into the data buffer but can't
  583. ensure all data in the data buffer are sent into the transmit shift buffer. */
  584. while (length--)
  585. {
  586. while (!(base->STAT & LPUART_STAT_TDRE_MASK))
  587. {
  588. }
  589. base->DATA = *(data++);
  590. }
  591. }
  592. status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)
  593. {
  594. assert(data);
  595. uint32_t statusFlag;
  596. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  597. uint32_t ctrl = base->CTRL;
  598. bool isSevenDataBits =
  599. ((ctrl & LPUART_CTRL_M7_MASK) ||
  600. ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
  601. #endif
  602. while (length--)
  603. {
  604. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  605. while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT))
  606. #else
  607. while (!(base->STAT & LPUART_STAT_RDRF_MASK))
  608. #endif
  609. {
  610. statusFlag = LPUART_GetStatusFlags(base);
  611. if (statusFlag & kLPUART_RxOverrunFlag)
  612. {
  613. LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag);
  614. return kStatus_LPUART_RxHardwareOverrun;
  615. }
  616. if (statusFlag & kLPUART_NoiseErrorFlag)
  617. {
  618. LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag);
  619. return kStatus_LPUART_NoiseError;
  620. }
  621. if (statusFlag & kLPUART_FramingErrorFlag)
  622. {
  623. LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag);
  624. return kStatus_LPUART_FramingError;
  625. }
  626. if (statusFlag & kLPUART_ParityErrorFlag)
  627. {
  628. LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag);
  629. return kStatus_LPUART_ParityError;
  630. }
  631. }
  632. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  633. if (isSevenDataBits)
  634. {
  635. *(data++) = (base->DATA & 0x7F);
  636. }
  637. else
  638. {
  639. *(data++) = base->DATA;
  640. }
  641. #else
  642. *(data++) = base->DATA;
  643. #endif
  644. }
  645. return kStatus_Success;
  646. }
  647. void LPUART_TransferCreateHandle(LPUART_Type *base,
  648. lpuart_handle_t *handle,
  649. lpuart_transfer_callback_t callback,
  650. void *userData)
  651. {
  652. assert(handle);
  653. uint32_t instance;
  654. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  655. uint32_t ctrl = base->CTRL;
  656. bool isSevenDataBits =
  657. ((ctrl & LPUART_CTRL_M7_MASK) ||
  658. ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
  659. #endif
  660. /* Zero the handle. */
  661. memset(handle, 0, sizeof(lpuart_handle_t));
  662. /* Set the TX/RX state. */
  663. handle->rxState = kLPUART_RxIdle;
  664. handle->txState = kLPUART_TxIdle;
  665. /* Set the callback and user data. */
  666. handle->callback = callback;
  667. handle->userData = userData;
  668. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  669. /* Initial seven data bits flag */
  670. handle->isSevenDataBits = isSevenDataBits;
  671. #endif
  672. /* Get instance from peripheral base address. */
  673. instance = LPUART_GetInstance(base);
  674. /* Save the handle in global variables to support the double weak mechanism. */
  675. s_lpuartHandle[instance] = handle;
  676. s_lpuartIsr = LPUART_TransferHandleIRQ;
  677. /* Enable interrupt in NVIC. */
  678. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  679. EnableIRQ(s_lpuartRxIRQ[instance]);
  680. EnableIRQ(s_lpuartTxIRQ[instance]);
  681. #else
  682. EnableIRQ(s_lpuartIRQ[instance]);
  683. #endif
  684. }
  685. void LPUART_TransferStartRingBuffer(LPUART_Type *base,
  686. lpuart_handle_t *handle,
  687. uint8_t *ringBuffer,
  688. size_t ringBufferSize)
  689. {
  690. assert(handle);
  691. assert(ringBuffer);
  692. /* Setup the ring buffer address */
  693. handle->rxRingBuffer = ringBuffer;
  694. handle->rxRingBufferSize = ringBufferSize;
  695. handle->rxRingBufferHead = 0U;
  696. handle->rxRingBufferTail = 0U;
  697. /* Enable the interrupt to accept the data when user need the ring buffer. */
  698. LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
  699. }
  700. void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle)
  701. {
  702. assert(handle);
  703. if (handle->rxState == kLPUART_RxIdle)
  704. {
  705. LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
  706. }
  707. handle->rxRingBuffer = NULL;
  708. handle->rxRingBufferSize = 0U;
  709. handle->rxRingBufferHead = 0U;
  710. handle->rxRingBufferTail = 0U;
  711. }
  712. status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer)
  713. {
  714. assert(handle);
  715. assert(xfer);
  716. assert(xfer->data);
  717. assert(xfer->dataSize);
  718. status_t status;
  719. /* Return error if current TX busy. */
  720. if (kLPUART_TxBusy == handle->txState)
  721. {
  722. status = kStatus_LPUART_TxBusy;
  723. }
  724. else
  725. {
  726. handle->txData = xfer->data;
  727. handle->txDataSize = xfer->dataSize;
  728. handle->txDataSizeAll = xfer->dataSize;
  729. handle->txState = kLPUART_TxBusy;
  730. /* Enable transmiter interrupt. */
  731. LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable);
  732. status = kStatus_Success;
  733. }
  734. return status;
  735. }
  736. void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle)
  737. {
  738. assert(handle);
  739. LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable);
  740. handle->txDataSize = 0;
  741. handle->txState = kLPUART_TxIdle;
  742. }
  743. status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
  744. {
  745. assert(handle);
  746. assert(count);
  747. if (kLPUART_TxIdle == handle->txState)
  748. {
  749. return kStatus_NoTransferInProgress;
  750. }
  751. *count = handle->txDataSizeAll - handle->txDataSize;
  752. return kStatus_Success;
  753. }
  754. status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
  755. lpuart_handle_t *handle,
  756. lpuart_transfer_t *xfer,
  757. size_t *receivedBytes)
  758. {
  759. assert(handle);
  760. assert(xfer);
  761. assert(xfer->data);
  762. assert(xfer->dataSize);
  763. uint32_t i;
  764. status_t status;
  765. /* How many bytes to copy from ring buffer to user memory. */
  766. size_t bytesToCopy = 0U;
  767. /* How many bytes to receive. */
  768. size_t bytesToReceive;
  769. /* How many bytes currently have received. */
  770. size_t bytesCurrentReceived;
  771. /* How to get data:
  772. 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
  773. to lpuart handle, enable interrupt to store received data to xfer->data. When
  774. all data received, trigger callback.
  775. 2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
  776. If there are enough data in ring buffer, copy them to xfer->data and return.
  777. If there are not enough data in ring buffer, copy all of them to xfer->data,
  778. save the xfer->data remained empty space to lpuart handle, receive data
  779. to this empty space and trigger callback when finished. */
  780. if (kLPUART_RxBusy == handle->rxState)
  781. {
  782. status = kStatus_LPUART_RxBusy;
  783. }
  784. else
  785. {
  786. bytesToReceive = xfer->dataSize;
  787. bytesCurrentReceived = 0;
  788. /* If RX ring buffer is used. */
  789. if (handle->rxRingBuffer)
  790. {
  791. /* Disable LPUART RX IRQ, protect ring buffer. */
  792. LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
  793. /* How many bytes in RX ring buffer currently. */
  794. bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
  795. if (bytesToCopy)
  796. {
  797. bytesToCopy = MIN(bytesToReceive, bytesToCopy);
  798. bytesToReceive -= bytesToCopy;
  799. /* Copy data from ring buffer to user memory. */
  800. for (i = 0U; i < bytesToCopy; i++)
  801. {
  802. xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
  803. /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
  804. if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
  805. {
  806. handle->rxRingBufferTail = 0U;
  807. }
  808. else
  809. {
  810. handle->rxRingBufferTail++;
  811. }
  812. }
  813. }
  814. /* If ring buffer does not have enough data, still need to read more data. */
  815. if (bytesToReceive)
  816. {
  817. /* No data in ring buffer, save the request to LPUART handle. */
  818. handle->rxData = xfer->data + bytesCurrentReceived;
  819. handle->rxDataSize = bytesToReceive;
  820. handle->rxDataSizeAll = bytesToReceive;
  821. handle->rxState = kLPUART_RxBusy;
  822. }
  823. /* Enable LPUART RX IRQ if previously enabled. */
  824. LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
  825. /* Call user callback since all data are received. */
  826. if (0 == bytesToReceive)
  827. {
  828. if (handle->callback)
  829. {
  830. handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
  831. }
  832. }
  833. }
  834. /* Ring buffer not used. */
  835. else
  836. {
  837. handle->rxData = xfer->data + bytesCurrentReceived;
  838. handle->rxDataSize = bytesToReceive;
  839. handle->rxDataSizeAll = bytesToReceive;
  840. handle->rxState = kLPUART_RxBusy;
  841. /* Enable RX interrupt. */
  842. LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable |
  843. kLPUART_IdleLineInterruptEnable);
  844. }
  845. /* Return the how many bytes have read. */
  846. if (receivedBytes)
  847. {
  848. *receivedBytes = bytesCurrentReceived;
  849. }
  850. status = kStatus_Success;
  851. }
  852. return status;
  853. }
  854. void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle)
  855. {
  856. assert(handle);
  857. /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
  858. if (!handle->rxRingBuffer)
  859. {
  860. /* Disable RX interrupt. */
  861. LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable |
  862. kLPUART_IdleLineInterruptEnable);
  863. }
  864. handle->rxDataSize = 0U;
  865. handle->rxState = kLPUART_RxIdle;
  866. }
  867. status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
  868. {
  869. assert(handle);
  870. assert(count);
  871. if (kLPUART_RxIdle == handle->rxState)
  872. {
  873. return kStatus_NoTransferInProgress;
  874. }
  875. *count = handle->rxDataSizeAll - handle->rxDataSize;
  876. return kStatus_Success;
  877. }
  878. void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
  879. {
  880. assert(handle);
  881. uint8_t count;
  882. uint8_t tempCount;
  883. /* If RX overrun. */
  884. if (LPUART_STAT_OR_MASK & base->STAT)
  885. {
  886. /* Clear overrun flag, otherwise the RX does not work. */
  887. base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK);
  888. /* Trigger callback. */
  889. if (handle->callback)
  890. {
  891. handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData);
  892. }
  893. }
  894. /* If IDLE flag is set and the IDLE interrupt is enabled. */
  895. if ((LPUART_STAT_IDLE_MASK & base->STAT) && (LPUART_CTRL_ILIE_MASK & base->CTRL))
  896. {
  897. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  898. count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
  899. while ((count) && (handle->rxDataSize))
  900. {
  901. tempCount = MIN(handle->rxDataSize, count);
  902. /* Using non block API to read the data from the registers. */
  903. LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
  904. handle->rxData += tempCount;
  905. handle->rxDataSize -= tempCount;
  906. count -= tempCount;
  907. /* If rxDataSize is 0, disable idle line interrupt.*/
  908. if (!(handle->rxDataSize))
  909. {
  910. handle->rxState = kLPUART_RxIdle;
  911. LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
  912. if (handle->callback)
  913. {
  914. handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
  915. }
  916. }
  917. }
  918. #endif
  919. /* Clear IDLE flag.*/
  920. base->STAT |= LPUART_STAT_IDLE_MASK;
  921. /* If rxDataSize is 0, disable idle line interrupt.*/
  922. if (!(handle->rxDataSize))
  923. {
  924. LPUART_DisableInterrupts(base, kLPUART_IdleLineInterruptEnable);
  925. }
  926. /* If callback is not NULL and rxDataSize is not 0. */
  927. if ((handle->callback) && (handle->rxDataSize))
  928. {
  929. handle->callback(base, handle, kStatus_LPUART_IdleLineDetected, handle->userData);
  930. }
  931. }
  932. /* Receive data register full */
  933. if ((LPUART_STAT_RDRF_MASK & base->STAT) && (LPUART_CTRL_RIE_MASK & base->CTRL))
  934. {
  935. /* Get the size that can be stored into buffer for this interrupt. */
  936. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  937. count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
  938. #else
  939. count = 1;
  940. #endif
  941. /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
  942. while ((count) && (handle->rxDataSize))
  943. {
  944. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  945. tempCount = MIN(handle->rxDataSize, count);
  946. #else
  947. tempCount = 1;
  948. #endif
  949. /* Using non block API to read the data from the registers. */
  950. LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
  951. handle->rxData += tempCount;
  952. handle->rxDataSize -= tempCount;
  953. count -= tempCount;
  954. /* If all the data required for upper layer is ready, trigger callback. */
  955. if (!handle->rxDataSize)
  956. {
  957. handle->rxState = kLPUART_RxIdle;
  958. if (handle->callback)
  959. {
  960. handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
  961. }
  962. }
  963. }
  964. /* If use RX ring buffer, receive data to ring buffer. */
  965. if (handle->rxRingBuffer)
  966. {
  967. while (count--)
  968. {
  969. /* If RX ring buffer is full, trigger callback to notify over run. */
  970. if (LPUART_TransferIsRxRingBufferFull(base, handle))
  971. {
  972. if (handle->callback)
  973. {
  974. handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData);
  975. }
  976. }
  977. /* If ring buffer is still full after callback function, the oldest data is overrided. */
  978. if (LPUART_TransferIsRxRingBufferFull(base, handle))
  979. {
  980. /* Increase handle->rxRingBufferTail to make room for new data. */
  981. if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
  982. {
  983. handle->rxRingBufferTail = 0U;
  984. }
  985. else
  986. {
  987. handle->rxRingBufferTail++;
  988. }
  989. }
  990. /* Read data. */
  991. #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
  992. if (handle->isSevenDataBits)
  993. {
  994. handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F);
  995. }
  996. else
  997. {
  998. handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
  999. }
  1000. #else
  1001. handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
  1002. #endif
  1003. /* Increase handle->rxRingBufferHead. */
  1004. if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
  1005. {
  1006. handle->rxRingBufferHead = 0U;
  1007. }
  1008. else
  1009. {
  1010. handle->rxRingBufferHead++;
  1011. }
  1012. }
  1013. }
  1014. /* If no receive requst pending, stop RX interrupt. */
  1015. else if (!handle->rxDataSize)
  1016. {
  1017. LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
  1018. }
  1019. else
  1020. {
  1021. }
  1022. }
  1023. /* Send data register empty and the interrupt is enabled. */
  1024. if ((base->STAT & LPUART_STAT_TDRE_MASK) && (base->CTRL & LPUART_CTRL_TIE_MASK))
  1025. {
  1026. /* Get the bytes that available at this moment. */
  1027. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  1028. count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) -
  1029. ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT);
  1030. #else
  1031. count = 1;
  1032. #endif
  1033. while ((count) && (handle->txDataSize))
  1034. {
  1035. #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
  1036. tempCount = MIN(handle->txDataSize, count);
  1037. #else
  1038. tempCount = 1;
  1039. #endif
  1040. /* Using non block API to write the data to the registers. */
  1041. LPUART_WriteNonBlocking(base, handle->txData, tempCount);
  1042. handle->txData += tempCount;
  1043. handle->txDataSize -= tempCount;
  1044. count -= tempCount;
  1045. /* If all the data are written to data register, notify user with the callback, then TX finished. */
  1046. if (!handle->txDataSize)
  1047. {
  1048. handle->txState = kLPUART_TxIdle;
  1049. /* Disable TX register empty interrupt. */
  1050. base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK);
  1051. /* Trigger callback. */
  1052. if (handle->callback)
  1053. {
  1054. handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData);
  1055. }
  1056. }
  1057. }
  1058. }
  1059. }
  1060. void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle)
  1061. {
  1062. /* To be implemented by User. */
  1063. }
  1064. #if defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1
  1065. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1066. void LPUART0_LPUART1_RX_DriverIRQHandler(void)
  1067. {
  1068. if (CLOCK_isEnabledClock(s_lpuartClock[0]))
  1069. {
  1070. if ((LPUART_STAT_OR_MASK & LPUART0->STAT) ||
  1071. ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL)))
  1072. {
  1073. s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
  1074. }
  1075. }
  1076. if (CLOCK_isEnabledClock(s_lpuartClock[1]))
  1077. {
  1078. if ((LPUART_STAT_OR_MASK & LPUART1->STAT) ||
  1079. ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL)))
  1080. {
  1081. s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
  1082. }
  1083. }
  1084. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1085. exception return operation might vector to incorrect interrupt */
  1086. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1087. __DSB();
  1088. #endif
  1089. }
  1090. void LPUART0_LPUART1_TX_DriverIRQHandler(void)
  1091. {
  1092. if (CLOCK_isEnabledClock(s_lpuartClock[0]))
  1093. {
  1094. if ((LPUART_STAT_OR_MASK & LPUART0->STAT) ||
  1095. ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK)))
  1096. {
  1097. s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
  1098. }
  1099. }
  1100. if (CLOCK_isEnabledClock(s_lpuartClock[1]))
  1101. {
  1102. if ((LPUART_STAT_OR_MASK & LPUART1->STAT) ||
  1103. ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK)))
  1104. {
  1105. s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
  1106. }
  1107. }
  1108. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1109. exception return operation might vector to incorrect interrupt */
  1110. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1111. __DSB();
  1112. #endif
  1113. }
  1114. #else
  1115. void LPUART0_LPUART1_DriverIRQHandler(void)
  1116. {
  1117. if (CLOCK_isEnabledClock(s_lpuartClock[0]))
  1118. {
  1119. if ((LPUART_STAT_OR_MASK & LPUART0->STAT) ||
  1120. ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL)) ||
  1121. ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK)))
  1122. {
  1123. s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
  1124. }
  1125. }
  1126. if (CLOCK_isEnabledClock(s_lpuartClock[1]))
  1127. {
  1128. if ((LPUART_STAT_OR_MASK & LPUART1->STAT) ||
  1129. ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL)) ||
  1130. ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK)))
  1131. {
  1132. s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
  1133. }
  1134. }
  1135. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1136. exception return operation might vector to incorrect interrupt */
  1137. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1138. __DSB();
  1139. #endif
  1140. }
  1141. #endif
  1142. #endif
  1143. #if defined(LPUART0)
  1144. #if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1)
  1145. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1146. void LPUART0_TX_DriverIRQHandler(void)
  1147. {
  1148. s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
  1149. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1150. exception return operation might vector to incorrect interrupt */
  1151. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1152. __DSB();
  1153. #endif
  1154. }
  1155. void LPUART0_RX_DriverIRQHandler(void)
  1156. {
  1157. s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
  1158. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1159. exception return operation might vector to incorrect interrupt */
  1160. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1161. __DSB();
  1162. #endif
  1163. }
  1164. #else
  1165. void LPUART0_DriverIRQHandler(void)
  1166. {
  1167. s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
  1168. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1169. exception return operation might vector to incorrect interrupt */
  1170. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1171. __DSB();
  1172. #endif
  1173. }
  1174. #endif
  1175. #endif
  1176. #endif
  1177. #if defined(LPUART1)
  1178. #if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1)
  1179. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1180. void LPUART1_TX_DriverIRQHandler(void)
  1181. {
  1182. s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
  1183. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1184. exception return operation might vector to incorrect interrupt */
  1185. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1186. __DSB();
  1187. #endif
  1188. }
  1189. void LPUART1_RX_DriverIRQHandler(void)
  1190. {
  1191. s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
  1192. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1193. exception return operation might vector to incorrect interrupt */
  1194. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1195. __DSB();
  1196. #endif
  1197. }
  1198. #else
  1199. void LPUART1_DriverIRQHandler(void)
  1200. {
  1201. s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
  1202. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1203. exception return operation might vector to incorrect interrupt */
  1204. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1205. __DSB();
  1206. #endif
  1207. }
  1208. #endif
  1209. #endif
  1210. #endif
  1211. #if defined(LPUART2)
  1212. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1213. void LPUART2_TX_DriverIRQHandler(void)
  1214. {
  1215. s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
  1216. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1217. exception return operation might vector to incorrect interrupt */
  1218. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1219. __DSB();
  1220. #endif
  1221. }
  1222. void LPUART2_RX_DriverIRQHandler(void)
  1223. {
  1224. s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
  1225. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1226. exception return operation might vector to incorrect interrupt */
  1227. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1228. __DSB();
  1229. #endif
  1230. }
  1231. #else
  1232. void LPUART2_DriverIRQHandler(void)
  1233. {
  1234. s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
  1235. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1236. exception return operation might vector to incorrect interrupt */
  1237. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1238. __DSB();
  1239. #endif
  1240. }
  1241. #endif
  1242. #endif
  1243. #if defined(LPUART3)
  1244. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1245. void LPUART3_TX_DriverIRQHandler(void)
  1246. {
  1247. s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
  1248. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1249. exception return operation might vector to incorrect interrupt */
  1250. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1251. __DSB();
  1252. #endif
  1253. }
  1254. void LPUART3_RX_DriverIRQHandler(void)
  1255. {
  1256. s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
  1257. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1258. exception return operation might vector to incorrect interrupt */
  1259. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1260. __DSB();
  1261. #endif
  1262. }
  1263. #else
  1264. void LPUART3_DriverIRQHandler(void)
  1265. {
  1266. s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
  1267. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1268. exception return operation might vector to incorrect interrupt */
  1269. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1270. __DSB();
  1271. #endif
  1272. }
  1273. #endif
  1274. #endif
  1275. #if defined(LPUART4)
  1276. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1277. void LPUART4_TX_DriverIRQHandler(void)
  1278. {
  1279. s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
  1280. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1281. exception return operation might vector to incorrect interrupt */
  1282. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1283. __DSB();
  1284. #endif
  1285. }
  1286. void LPUART4_RX_DriverIRQHandler(void)
  1287. {
  1288. s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
  1289. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1290. exception return operation might vector to incorrect interrupt */
  1291. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1292. __DSB();
  1293. #endif
  1294. }
  1295. #else
  1296. void LPUART4_DriverIRQHandler(void)
  1297. {
  1298. s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
  1299. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1300. exception return operation might vector to incorrect interrupt */
  1301. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1302. __DSB();
  1303. #endif
  1304. }
  1305. #endif
  1306. #endif
  1307. #if defined(LPUART5)
  1308. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1309. void LPUART5_TX_DriverIRQHandler(void)
  1310. {
  1311. s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
  1312. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1313. exception return operation might vector to incorrect interrupt */
  1314. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1315. __DSB();
  1316. #endif
  1317. }
  1318. void LPUART5_RX_DriverIRQHandler(void)
  1319. {
  1320. s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
  1321. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1322. exception return operation might vector to incorrect interrupt */
  1323. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1324. __DSB();
  1325. #endif
  1326. }
  1327. #else
  1328. void LPUART5_DriverIRQHandler(void)
  1329. {
  1330. s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
  1331. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1332. exception return operation might vector to incorrect interrupt */
  1333. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1334. __DSB();
  1335. #endif
  1336. }
  1337. #endif
  1338. #endif
  1339. #if defined(LPUART6)
  1340. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1341. void LPUART6_TX_DriverIRQHandler(void)
  1342. {
  1343. s_lpuartIsr(LPUART6, s_lpuartHandle[6]);
  1344. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1345. exception return operation might vector to incorrect interrupt */
  1346. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1347. __DSB();
  1348. #endif
  1349. }
  1350. void LPUART6_RX_DriverIRQHandler(void)
  1351. {
  1352. s_lpuartIsr(LPUART6, s_lpuartHandle[6]);
  1353. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1354. exception return operation might vector to incorrect interrupt */
  1355. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1356. __DSB();
  1357. #endif
  1358. }
  1359. #else
  1360. void LPUART6_DriverIRQHandler(void)
  1361. {
  1362. s_lpuartIsr(LPUART6, s_lpuartHandle[6]);
  1363. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1364. exception return operation might vector to incorrect interrupt */
  1365. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1366. __DSB();
  1367. #endif
  1368. }
  1369. #endif
  1370. #endif
  1371. #if defined(LPUART7)
  1372. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1373. void LPUART7_TX_DriverIRQHandler(void)
  1374. {
  1375. s_lpuartIsr(LPUART7, s_lpuartHandle[7]);
  1376. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1377. exception return operation might vector to incorrect interrupt */
  1378. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1379. __DSB();
  1380. #endif
  1381. }
  1382. void LPUART7_RX_DriverIRQHandler(void)
  1383. {
  1384. s_lpuartIsr(LPUART7, s_lpuartHandle[7]);
  1385. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1386. exception return operation might vector to incorrect interrupt */
  1387. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1388. __DSB();
  1389. #endif
  1390. }
  1391. #else
  1392. void LPUART7_DriverIRQHandler(void)
  1393. {
  1394. s_lpuartIsr(LPUART7, s_lpuartHandle[7]);
  1395. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1396. exception return operation might vector to incorrect interrupt */
  1397. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1398. __DSB();
  1399. #endif
  1400. }
  1401. #endif
  1402. #endif
  1403. #if defined(LPUART8)
  1404. #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
  1405. void LPUART8_TX_DriverIRQHandler(void)
  1406. {
  1407. s_lpuartIsr(LPUART8, s_lpuartHandle[8]);
  1408. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1409. exception return operation might vector to incorrect interrupt */
  1410. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1411. __DSB();
  1412. #endif
  1413. }
  1414. void LPUART8_RX_DriverIRQHandler(void)
  1415. {
  1416. s_lpuartIsr(LPUART8, s_lpuartHandle[8]);
  1417. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1418. exception return operation might vector to incorrect interrupt */
  1419. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1420. __DSB();
  1421. #endif
  1422. }
  1423. #else
  1424. void LPUART8_DriverIRQHandler(void)
  1425. {
  1426. s_lpuartIsr(LPUART8, s_lpuartHandle[8]);
  1427. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1428. exception return operation might vector to incorrect interrupt */
  1429. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1430. __DSB();
  1431. #endif
  1432. }
  1433. #endif
  1434. #endif
  1435. #if defined(CM4_0__LPUART)
  1436. void M4_0_LPUART_DriverIRQHandler(void)
  1437. {
  1438. s_lpuartIsr(CM4_0__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_0__LPUART)]);
  1439. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1440. exception return operation might vector to incorrect interrupt */
  1441. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1442. __DSB();
  1443. #endif
  1444. }
  1445. #endif
  1446. #if defined(CM4_1__LPUART)
  1447. void M4_1_LPUART_DriverIRQHandler(void)
  1448. {
  1449. s_lpuartIsr(CM4_1__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_1__LPUART)]);
  1450. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1451. exception return operation might vector to incorrect interrupt */
  1452. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1453. __DSB();
  1454. #endif
  1455. }
  1456. #endif
  1457. #if defined(DMA__LPUART0)
  1458. void DMA_UART0_INT_IRQHandler(void)
  1459. {
  1460. s_lpuartIsr(DMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART0)]);
  1461. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1462. exception return operation might vector to incorrect interrupt */
  1463. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1464. __DSB();
  1465. #endif
  1466. }
  1467. #endif
  1468. #if defined(DMA__LPUART1)
  1469. void DMA_UART1_INT_IRQHandler(void)
  1470. {
  1471. s_lpuartIsr(DMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART1)]);
  1472. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1473. exception return operation might vector to incorrect interrupt */
  1474. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1475. __DSB();
  1476. #endif
  1477. }
  1478. #endif
  1479. #if defined(DMA__LPUART2)
  1480. void DMA_UART2_INT_IRQHandler(void)
  1481. {
  1482. s_lpuartIsr(DMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART2)]);
  1483. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1484. exception return operation might vector to incorrect interrupt */
  1485. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1486. __DSB();
  1487. #endif
  1488. }
  1489. #endif
  1490. #if defined(DMA__LPUART3)
  1491. void DMA_UART3_INT_IRQHandler(void)
  1492. {
  1493. s_lpuartIsr(DMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART3)]);
  1494. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1495. exception return operation might vector to incorrect interrupt */
  1496. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1497. __DSB();
  1498. #endif
  1499. }
  1500. #endif
  1501. #if defined(DMA__LPUART4)
  1502. void DMA_UART4_INT_IRQHandler(void)
  1503. {
  1504. s_lpuartIsr(DMA__LPUART4, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART4)]);
  1505. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1506. exception return operation might vector to incorrect interrupt */
  1507. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1508. __DSB();
  1509. #endif
  1510. }
  1511. #endif