fsl_flexio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_flexio.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.flexio"
  15. #endif
  16. /*< @brief user configurable flexio handle count. */
  17. #define FLEXIO_HANDLE_COUNT 2
  18. /*******************************************************************************
  19. * Variables
  20. ******************************************************************************/
  21. /*! @brief Pointers to flexio bases for each instance. */
  22. FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS;
  23. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  24. /*! @brief Pointers to flexio clocks for each instance. */
  25. const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS;
  26. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  27. /*< @brief pointer to array of FLEXIO handle. */
  28. static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
  29. /*< @brief pointer to array of FLEXIO IP types. */
  30. static void *s_flexioType[FLEXIO_HANDLE_COUNT];
  31. /*< @brief pointer to array of FLEXIO Isr. */
  32. static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
  33. /* FlexIO common IRQ Handler. */
  34. static void FLEXIO_CommonIRQHandler(void);
  35. /*******************************************************************************
  36. * Codes
  37. ******************************************************************************/
  38. /*!
  39. * brief Get instance number for FLEXIO module.
  40. *
  41. * param base FLEXIO peripheral base address.
  42. */
  43. uint32_t FLEXIO_GetInstance(FLEXIO_Type *base)
  44. {
  45. uint32_t instance;
  46. /* Find the instance index from base address mappings. */
  47. for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++)
  48. {
  49. if (s_flexioBases[instance] == base)
  50. {
  51. break;
  52. }
  53. }
  54. assert(instance < ARRAY_SIZE(s_flexioBases));
  55. return instance;
  56. }
  57. /*!
  58. * brief Configures the FlexIO with a FlexIO configuration. The configuration structure
  59. * can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig().
  60. *
  61. * Example
  62. code
  63. flexio_config_t config = {
  64. .enableFlexio = true,
  65. .enableInDoze = false,
  66. .enableInDebug = true,
  67. .enableFastAccess = false
  68. };
  69. FLEXIO_Configure(base, &config);
  70. endcode
  71. *
  72. * param base FlexIO peripheral base address
  73. * param userConfig pointer to flexio_config_t structure
  74. */
  75. void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
  76. {
  77. uint32_t ctrlReg = 0;
  78. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  79. CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
  80. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  81. FLEXIO_Reset(base);
  82. ctrlReg = base->CTRL;
  83. ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
  84. ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
  85. FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
  86. if (!userConfig->enableInDoze)
  87. {
  88. ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
  89. }
  90. base->CTRL = ctrlReg;
  91. }
  92. /*!
  93. * brief Gates the FlexIO clock. Call this API to stop the FlexIO clock.
  94. *
  95. * note After calling this API, call the FLEXO_Init to use the FlexIO module.
  96. *
  97. * param base FlexIO peripheral base address
  98. */
  99. void FLEXIO_Deinit(FLEXIO_Type *base)
  100. {
  101. FLEXIO_Enable(base, false);
  102. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  103. CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
  104. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  105. }
  106. /*!
  107. * brief Gets the default configuration to configure the FlexIO module. The configuration
  108. * can used directly to call the FLEXIO_Configure().
  109. *
  110. * Example:
  111. code
  112. flexio_config_t config;
  113. FLEXIO_GetDefaultConfig(&config);
  114. endcode
  115. *
  116. * param userConfig pointer to flexio_config_t structure
  117. */
  118. void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
  119. {
  120. assert(userConfig != NULL);
  121. /* Initializes the configure structure to zero. */
  122. (void)memset(userConfig, 0, sizeof(*userConfig));
  123. userConfig->enableFlexio = true;
  124. userConfig->enableInDoze = false;
  125. userConfig->enableInDebug = true;
  126. userConfig->enableFastAccess = false;
  127. }
  128. /*!
  129. * brief Resets the FlexIO module.
  130. *
  131. * param base FlexIO peripheral base address
  132. */
  133. void FLEXIO_Reset(FLEXIO_Type *base)
  134. {
  135. /*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
  136. base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
  137. base->CTRL = 0;
  138. }
  139. /*!
  140. * brief Gets the shifter buffer address for the DMA transfer usage.
  141. *
  142. * param base FlexIO peripheral base address
  143. * param type Shifter type of flexio_shifter_buffer_type_t
  144. * param index Shifter index
  145. * return Corresponding shifter buffer index
  146. */
  147. uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
  148. {
  149. assert(index < FLEXIO_SHIFTBUF_COUNT);
  150. uint32_t address = 0;
  151. switch (type)
  152. {
  153. case kFLEXIO_ShifterBuffer:
  154. address = (uint32_t) & (base->SHIFTBUF[index]);
  155. break;
  156. case kFLEXIO_ShifterBufferBitSwapped:
  157. address = (uint32_t) & (base->SHIFTBUFBIS[index]);
  158. break;
  159. case kFLEXIO_ShifterBufferByteSwapped:
  160. address = (uint32_t) & (base->SHIFTBUFBYS[index]);
  161. break;
  162. case kFLEXIO_ShifterBufferBitByteSwapped:
  163. address = (uint32_t) & (base->SHIFTBUFBBS[index]);
  164. break;
  165. #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
  166. case kFLEXIO_ShifterBufferNibbleByteSwapped:
  167. address = (uint32_t) & (base->SHIFTBUFNBS[index]);
  168. break;
  169. #endif
  170. #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
  171. case kFLEXIO_ShifterBufferHalfWordSwapped:
  172. address = (uint32_t) & (base->SHIFTBUFHWS[index]);
  173. break;
  174. #endif
  175. #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
  176. case kFLEXIO_ShifterBufferNibbleSwapped:
  177. address = (uint32_t) & (base->SHIFTBUFNIS[index]);
  178. break;
  179. #endif
  180. default:
  181. address = (uint32_t) & (base->SHIFTBUF[index]);
  182. break;
  183. }
  184. return address;
  185. }
  186. /*!
  187. * brief Configures the shifter with the shifter configuration. The configuration structure
  188. * covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper
  189. * mode, select which timer controls the shifter to shift, whether to generate start bit/stop
  190. * bit, and the polarity of start bit and stop bit.
  191. *
  192. * Example
  193. code
  194. flexio_shifter_config_t config = {
  195. .timerSelect = 0,
  196. .timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive,
  197. .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
  198. .pinPolarity = kFLEXIO_PinActiveLow,
  199. .shifterMode = kFLEXIO_ShifterModeTransmit,
  200. .inputSource = kFLEXIO_ShifterInputFromPin,
  201. .shifterStop = kFLEXIO_ShifterStopBitHigh,
  202. .shifterStart = kFLEXIO_ShifterStartBitLow
  203. };
  204. FLEXIO_SetShifterConfig(base, &config);
  205. endcode
  206. *
  207. * param base FlexIO peripheral base address
  208. * param index Shifter index
  209. * param shifterConfig Pointer to flexio_shifter_config_t structure
  210. */
  211. void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
  212. {
  213. base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
  214. #if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
  215. | FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
  216. #endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
  217. | FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
  218. FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
  219. base->SHIFTCTL[index] =
  220. FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
  221. FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
  222. FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
  223. }
  224. /*!
  225. * brief Configures the timer with the timer configuration. The configuration structure
  226. * covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper
  227. * mode, select trigger source for timer and the timer pin output and the timing for timer.
  228. *
  229. * Example
  230. code
  231. flexio_timer_config_t config = {
  232. .triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0),
  233. .triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow,
  234. .triggerSource = kFLEXIO_TimerTriggerSourceInternal,
  235. .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
  236. .pinSelect = 0,
  237. .pinPolarity = kFLEXIO_PinActiveHigh,
  238. .timerMode = kFLEXIO_TimerModeDual8BitBaudBit,
  239. .timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset,
  240. .timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput,
  241. .timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput,
  242. .timerDisable = kFLEXIO_TimerDisableOnTimerCompare,
  243. .timerEnable = kFLEXIO_TimerEnableOnTriggerHigh,
  244. .timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable,
  245. .timerStart = kFLEXIO_TimerStartBitEnabled
  246. };
  247. FLEXIO_SetTimerConfig(base, &config);
  248. endcode
  249. *
  250. * param base FlexIO peripheral base address
  251. * param index Timer index
  252. * param timerConfig Pointer to the flexio_timer_config_t structure
  253. */
  254. void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
  255. {
  256. base->TIMCFG[index] =
  257. FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
  258. FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
  259. FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
  260. FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
  261. base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
  262. base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
  263. FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
  264. FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
  265. FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
  266. FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
  267. }
  268. /*!
  269. * brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral.
  270. *
  271. * param base Pointer to the FlexIO simulated peripheral type.
  272. * param handle Pointer to the handler for FlexIO simulated peripheral.
  273. * param isr FlexIO simulated peripheral interrupt handler.
  274. * retval kStatus_Success Successfully create the handle.
  275. * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
  276. */
  277. status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
  278. {
  279. assert(base != NULL);
  280. assert(handle != NULL);
  281. assert(isr != NULL);
  282. uint8_t index;
  283. /* Find the an empty handle pointer to store the handle. */
  284. for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
  285. {
  286. if (s_flexioHandle[index] == NULL)
  287. {
  288. /* Register FLEXIO simulated driver base, handle and isr. */
  289. s_flexioType[index] = base;
  290. s_flexioHandle[index] = handle;
  291. s_flexioIsr[index] = isr;
  292. break;
  293. }
  294. }
  295. if (index == (uint8_t)FLEXIO_HANDLE_COUNT)
  296. {
  297. return kStatus_OutOfRange;
  298. }
  299. else
  300. {
  301. return kStatus_Success;
  302. }
  303. }
  304. /*!
  305. * brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral.
  306. *
  307. * param base Pointer to the FlexIO simulated peripheral type.
  308. * retval kStatus_Success Successfully create the handle.
  309. * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
  310. */
  311. status_t FLEXIO_UnregisterHandleIRQ(void *base)
  312. {
  313. assert(base != NULL);
  314. uint8_t index;
  315. /* Find the index from base address mappings. */
  316. for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
  317. {
  318. if (s_flexioType[index] == base)
  319. {
  320. /* Unregister FLEXIO simulated driver handle and isr. */
  321. s_flexioType[index] = NULL;
  322. s_flexioHandle[index] = NULL;
  323. s_flexioIsr[index] = NULL;
  324. break;
  325. }
  326. }
  327. if (index == (uint8_t)FLEXIO_HANDLE_COUNT)
  328. {
  329. return kStatus_OutOfRange;
  330. }
  331. else
  332. {
  333. return kStatus_Success;
  334. }
  335. }
  336. static void FLEXIO_CommonIRQHandler(void)
  337. {
  338. uint8_t index;
  339. for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++)
  340. {
  341. if (s_flexioHandle[index] != NULL)
  342. {
  343. s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
  344. }
  345. }
  346. SDK_ISR_EXIT_BARRIER;
  347. }
  348. void FLEXIO_DriverIRQHandler(void);
  349. void FLEXIO_DriverIRQHandler(void)
  350. {
  351. FLEXIO_CommonIRQHandler();
  352. }
  353. void FLEXIO0_DriverIRQHandler(void);
  354. void FLEXIO0_DriverIRQHandler(void)
  355. {
  356. FLEXIO_CommonIRQHandler();
  357. }
  358. void FLEXIO1_DriverIRQHandler(void);
  359. void FLEXIO1_DriverIRQHandler(void)
  360. {
  361. FLEXIO_CommonIRQHandler();
  362. }
  363. void UART2_FLEXIO_DriverIRQHandler(void);
  364. void UART2_FLEXIO_DriverIRQHandler(void)
  365. {
  366. FLEXIO_CommonIRQHandler();
  367. }
  368. void FLEXIO2_DriverIRQHandler(void);
  369. void FLEXIO2_DriverIRQHandler(void)
  370. {
  371. FLEXIO_CommonIRQHandler();
  372. }
  373. void FLEXIO3_DriverIRQHandler(void);
  374. void FLEXIO3_DriverIRQHandler(void)
  375. {
  376. FLEXIO_CommonIRQHandler();
  377. }