fsl_flexio.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_flexio.h"
  35. /*******************************************************************************
  36. * Definitions
  37. ******************************************************************************/
  38. /* Component ID definition, used by tools. */
  39. #ifndef FSL_COMPONENT_ID
  40. #define FSL_COMPONENT_ID "platform.drivers.flexio"
  41. #endif
  42. /*< @brief user configurable flexio handle count. */
  43. #define FLEXIO_HANDLE_COUNT 2
  44. /*******************************************************************************
  45. * Variables
  46. ******************************************************************************/
  47. /*! @brief Pointers to flexio bases for each instance. */
  48. FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS;
  49. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  50. /*! @brief Pointers to flexio clocks for each instance. */
  51. const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS;
  52. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  53. /*< @brief pointer to array of FLEXIO handle. */
  54. static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
  55. /*< @brief pointer to array of FLEXIO IP types. */
  56. static void *s_flexioType[FLEXIO_HANDLE_COUNT];
  57. /*< @brief pointer to array of FLEXIO Isr. */
  58. static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
  59. /*******************************************************************************
  60. * Codes
  61. ******************************************************************************/
  62. uint32_t FLEXIO_GetInstance(FLEXIO_Type *base)
  63. {
  64. uint32_t instance;
  65. /* Find the instance index from base address mappings. */
  66. for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++)
  67. {
  68. if (s_flexioBases[instance] == base)
  69. {
  70. break;
  71. }
  72. }
  73. assert(instance < ARRAY_SIZE(s_flexioBases));
  74. return instance;
  75. }
  76. void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
  77. {
  78. uint32_t ctrlReg = 0;
  79. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  80. CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
  81. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  82. FLEXIO_Reset(base);
  83. ctrlReg = base->CTRL;
  84. ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
  85. ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
  86. FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
  87. if (!userConfig->enableInDoze)
  88. {
  89. ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
  90. }
  91. base->CTRL = ctrlReg;
  92. }
  93. void FLEXIO_Deinit(FLEXIO_Type *base)
  94. {
  95. FLEXIO_Enable(base, false);
  96. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  97. CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
  98. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  99. }
  100. void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
  101. {
  102. assert(userConfig);
  103. userConfig->enableFlexio = true;
  104. userConfig->enableInDoze = false;
  105. userConfig->enableInDebug = true;
  106. userConfig->enableFastAccess = false;
  107. }
  108. void FLEXIO_Reset(FLEXIO_Type *base)
  109. {
  110. /*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
  111. base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
  112. base->CTRL = 0;
  113. }
  114. uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
  115. {
  116. assert(index < FLEXIO_SHIFTBUF_COUNT);
  117. uint32_t address = 0;
  118. switch (type)
  119. {
  120. case kFLEXIO_ShifterBuffer:
  121. address = (uint32_t) & (base->SHIFTBUF[index]);
  122. break;
  123. case kFLEXIO_ShifterBufferBitSwapped:
  124. address = (uint32_t) & (base->SHIFTBUFBIS[index]);
  125. break;
  126. case kFLEXIO_ShifterBufferByteSwapped:
  127. address = (uint32_t) & (base->SHIFTBUFBYS[index]);
  128. break;
  129. case kFLEXIO_ShifterBufferBitByteSwapped:
  130. address = (uint32_t) & (base->SHIFTBUFBBS[index]);
  131. break;
  132. #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
  133. case kFLEXIO_ShifterBufferNibbleByteSwapped:
  134. address = (uint32_t) & (base->SHIFTBUFNBS[index]);
  135. break;
  136. #endif
  137. #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
  138. case kFLEXIO_ShifterBufferHalfWordSwapped:
  139. address = (uint32_t) & (base->SHIFTBUFHWS[index]);
  140. break;
  141. #endif
  142. #if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
  143. case kFLEXIO_ShifterBufferNibbleSwapped:
  144. address = (uint32_t) & (base->SHIFTBUFNIS[index]);
  145. break;
  146. #endif
  147. default:
  148. break;
  149. }
  150. return address;
  151. }
  152. void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
  153. {
  154. base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
  155. #if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
  156. | FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
  157. #endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
  158. | FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
  159. FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
  160. base->SHIFTCTL[index] =
  161. FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
  162. FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
  163. FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
  164. }
  165. void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
  166. {
  167. base->TIMCFG[index] =
  168. FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
  169. FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
  170. FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
  171. FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
  172. base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
  173. base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
  174. FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
  175. FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
  176. FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
  177. FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
  178. }
  179. status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
  180. {
  181. assert(base);
  182. assert(handle);
  183. assert(isr);
  184. uint8_t index = 0;
  185. /* Find the an empty handle pointer to store the handle. */
  186. for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
  187. {
  188. if (s_flexioHandle[index] == NULL)
  189. {
  190. /* Register FLEXIO simulated driver base, handle and isr. */
  191. s_flexioType[index] = base;
  192. s_flexioHandle[index] = handle;
  193. s_flexioIsr[index] = isr;
  194. break;
  195. }
  196. }
  197. if (index == FLEXIO_HANDLE_COUNT)
  198. {
  199. return kStatus_OutOfRange;
  200. }
  201. else
  202. {
  203. return kStatus_Success;
  204. }
  205. }
  206. status_t FLEXIO_UnregisterHandleIRQ(void *base)
  207. {
  208. assert(base);
  209. uint8_t index = 0;
  210. /* Find the index from base address mappings. */
  211. for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
  212. {
  213. if (s_flexioType[index] == base)
  214. {
  215. /* Unregister FLEXIO simulated driver handle and isr. */
  216. s_flexioType[index] = NULL;
  217. s_flexioHandle[index] = NULL;
  218. s_flexioIsr[index] = NULL;
  219. break;
  220. }
  221. }
  222. if (index == FLEXIO_HANDLE_COUNT)
  223. {
  224. return kStatus_OutOfRange;
  225. }
  226. else
  227. {
  228. return kStatus_Success;
  229. }
  230. }
  231. void FLEXIO_CommonIRQHandler(void)
  232. {
  233. uint8_t index;
  234. for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
  235. {
  236. if (s_flexioHandle[index])
  237. {
  238. s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
  239. }
  240. }
  241. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  242. exception return operation might vector to incorrect interrupt */
  243. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  244. __DSB();
  245. #endif
  246. }
  247. void FLEXIO_DriverIRQHandler(void)
  248. {
  249. FLEXIO_CommonIRQHandler();
  250. }
  251. void FLEXIO0_DriverIRQHandler(void)
  252. {
  253. FLEXIO_CommonIRQHandler();
  254. }
  255. void FLEXIO1_DriverIRQHandler(void)
  256. {
  257. FLEXIO_CommonIRQHandler();
  258. }
  259. void UART2_FLEXIO_DriverIRQHandler(void)
  260. {
  261. FLEXIO_CommonIRQHandler();
  262. }
  263. void FLEXIO2_DriverIRQHandler(void)
  264. {
  265. FLEXIO_CommonIRQHandler();
  266. }