fioctrl.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * Copyright : (C) 2022 Phytium Information Technology, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is OPEN SOURCE software: you can redistribute it and/or modify it
  6. * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
  7. * either version 1.0 of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
  10. * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. * See the Phytium Public License for more details.
  12. *
  13. *
  14. * FilePath: fioctrl.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-02-18 08:25:29
  17. * Description:  This files is for io-ctrl function implementation (io-mux/io-config/io-delay)
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. * 1.0 zhugengyu 2022/2/22 init commit
  23. */
  24. /***************************** Include Files *********************************/
  25. #include "fparameters.h"
  26. #include "fio.h"
  27. #include "fkernel.h"
  28. #include "fassert.h"
  29. #include "fdebug.h"
  30. #include "fioctrl.h"
  31. #include "fpinctrl.h"
  32. /************************** Constant Definitions *****************************/
  33. /* Bit[0] : 输入延迟功能使能 */
  34. #define FIOCTRL_DELAY_EN(delay_beg) BIT(delay_beg)
  35. #define FIOCTRL_INPUT_DELAY_OFF 0
  36. /* Bit[3:1] : 输入延迟精调档位选择 */
  37. #define FIOCTRL_DELICATE_DELAY_MASK(delay_beg) GENMASK((delay_beg + 3), (delay_beg + 1))
  38. #define FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg) GET_REG32_BITS((reg_val), (delay_beg + 3), (delay_beg + 1))
  39. #define FIOCTRL_DELICATE_DELAY_SET(val, delay_beg) SET_REG32_BITS((val), (delay_beg + 3), (delay_beg + 1))
  40. /* Bit[6:4] : 输入延迟粗调档位选择 */
  41. #define FIOCTRL_ROUGH_DELAY_MASK(delay_beg) GENMASK((delay_beg + 6), (delay_beg + 4))
  42. #define FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg) GET_REG32_BITS((reg_val), (delay_beg + 6), (delay_beg + 4))
  43. #define FIOCTRL_ROUGH_DELAY_SET(val, delay_beg) SET_REG32_BITS((val), (delay_beg + 6), (delay_beg + 4))
  44. /* Bit[7] : 保留 */
  45. /* Bit[8] : 输出延迟功能使能 */
  46. /* Bit[11:9] : 输出延迟精调档位选择 */
  47. /* Bit [14:12] : 输出延迟粗调档位选择 */
  48. /* Bit [15] : 保留 */
  49. #define FIOCTRL_FUNC_BEG_OFF(reg_bit) ((reg_bit) + 0)
  50. #define FIOCTRL_FUNC_END_OFF(reg_bit) ((reg_bit) + 1) /* bit[1:0] 复用功能占2个位 */
  51. #define FIOCTRL_PULL_BEG_OFF(reg_bit) ((reg_bit) + 2)
  52. #define FIOCTRL_PULL_END_OFF(reg_bit) ((reg_bit) + 3) /* bit[3:2] 上下拉功能占2个位 */
  53. #define FIOCTRL_DELAY_IN_BEG_OFF(reg_bit) ((reg_bit) + 0)
  54. #define FIOCTRL_DELAY_IN_END_OFF(reg_bit) ((reg_bit) + 7) /* bit[8:1] 输入延时占7个位 */
  55. #define FIOCTRL_DELAY_OUT_BEG_OFF(reg_bit) ((reg_bit) + 8)
  56. #define FIOCTRL_DELAY_OUT_END_OFF(reg_bit) ((reg_bit) + 15) /* bit[15:9] 输出延时占7个位 */
  57. /* 芯片引脚控制寄存器的起止位置 */
  58. #define FIOCTRL_REG_OFFSET_MIN 0x200
  59. #define FIOCTRL_REG_OFFSET_MAX 0x22c
  60. /* 芯片引脚延时寄存器的起止位置 */
  61. #define FIOCTRL_DELAY_REG_OFFSET_MIN 0x400
  62. #define FIOCTRL_DELAY_REG_OFFSET_MAX 0x404
  63. /**************************** Type Definitions *******************************/
  64. /***************** Macros (Inline Functions) Definitions *********************/
  65. #define FIOCTRL_DEBUG_TAG "FIOCTRL"
  66. #define FIOCTRL_ERROR(format, ...) FT_DEBUG_PRINT_E(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__)
  67. #define FIOCTRL_WARN(format, ...) FT_DEBUG_PRINT_W(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__)
  68. #define FIOCTRL_INFO(format, ...) FT_DEBUG_PRINT_I(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__)
  69. #define FIOCTRL_DEBUG(format, ...) FT_DEBUG_PRINT_D(FIOCTRL_DEBUG_TAG, format, ##__VA_ARGS__)
  70. #define FIOCTRL_ASSERT_REG_OFF(pin) FASSERT_MSG(((pin.reg_off >= FIOCTRL_REG_OFFSET_MIN) && (pin.reg_off <= FIOCTRL_REG_OFFSET_MAX)), "invalid pin register off @%d", (pin.reg_off))
  71. #define FIOCTRL_ASSERT_FUNC(func) FASSERT_MSG((func < FPIN_NUM_OF_FUNC), "invalid func as %d", (func))
  72. #define FIOCTRL_ASSERT_PULL(pull) FASSERT_MSG((pull < FPIN_NUM_OF_PULL), "invalid pull as %d", (pull))
  73. #define FIOCTRL_ASSERT_DELAY_REG_OFF(pin) FASSERT_MSG(((pin.reg_off >= FIOCTRL_DELAY_REG_OFFSET_MIN) && (pin.reg_off <= FIOCTRL_DELAY_REG_OFFSET_MAX)), "invalid delay pin register off @%d", (pin.reg_off))
  74. #define FIOCTRL_ASSERT_DELAY(delay) FASSERT_MSG(((delay) < FPIN_NUM_OF_DELAY), "invalid delay as %d", (delay));
  75. /************************** Function Prototypes ******************************/
  76. /************************** Variable Definitions *****************************/
  77. /*****************************************************************************/
  78. /**
  79. * @name: FPinGetFunc
  80. * @msg: 获取IO引脚当前的复用功能
  81. * @return {FPinFunc} 当前的复用功能
  82. * @param {FPinIndex} pin IO引脚索引
  83. * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值
  84. */
  85. FPinFunc FPinGetFunc(const FPinIndex pin)
  86. {
  87. FIOCTRL_ASSERT_REG_OFF(pin);
  88. u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit);
  89. u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit);
  90. u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  91. u32 func = GET_REG32_BITS(reg_val, func_end, func_beg);
  92. FIOCTRL_ASSERT_FUNC(func);
  93. return (FPinFunc)GET_REG32_BITS(reg_val, func_end, func_beg);
  94. }
  95. /**
  96. * @name: FPinSetFunc
  97. * @msg: 设置IO引脚复用功能
  98. * @return {*}
  99. * @param {FPinIndex} pin IO引脚索引
  100. * @param {FPinFunc} func IO复用功能
  101. * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值
  102. */
  103. void FPinSetFunc(const FPinIndex pin, FPinFunc func)
  104. {
  105. FIOCTRL_ASSERT_REG_OFF(pin);
  106. FIOCTRL_ASSERT_FUNC(func);
  107. u32 func_beg = FIOCTRL_FUNC_BEG_OFF(pin.reg_bit);
  108. u32 func_end = FIOCTRL_FUNC_END_OFF(pin.reg_bit);
  109. u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  110. reg_val &= ~GENMASK(func_end, func_beg);
  111. reg_val |= SET_REG32_BITS(func, func_end, func_beg);
  112. FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val);
  113. return;
  114. }
  115. /**
  116. * @name: FPinGetPull
  117. * @msg: 获取IO引脚当前的上下拉设置
  118. * @return {*}
  119. * @param {FPinIndex} pin IO引脚索引
  120. * @note 参考编程手册,使用 FIOCTRL_INDEX 宏定义index的值
  121. */
  122. FPinPull FPinGetPull(const FPinIndex pin)
  123. {
  124. FIOCTRL_ASSERT_REG_OFF(pin);
  125. u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit);
  126. u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit);
  127. u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  128. u32 pull = GET_REG32_BITS(reg_val, pull_end, pull_beg);
  129. FIOCTRL_ASSERT_PULL(pull);
  130. return (FPinPull)pull;
  131. }
  132. /**
  133. * @name: FPinSetPull
  134. * @msg: 设置IO引脚当前的上下拉
  135. * @return {*}
  136. * @param {FPinIndex} pin IO引脚索引
  137. * @param {FPinPull} pull 上下拉设置
  138. */
  139. void FPinSetPull(const FPinIndex pin, FPinPull pull)
  140. {
  141. FIOCTRL_ASSERT_REG_OFF(pin);
  142. FIOCTRL_ASSERT_PULL(pull);
  143. u32 pull_beg = FIOCTRL_PULL_BEG_OFF(pin.reg_bit);
  144. u32 pull_end = FIOCTRL_PULL_END_OFF(pin.reg_bit);
  145. u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  146. reg_val &= ~GENMASK(pull_end, pull_beg);
  147. reg_val |= SET_REG32_BITS(pull, pull_end, pull_beg);
  148. FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val);
  149. return;
  150. }
  151. /**
  152. * @name: FPinGetDelay
  153. * @msg: 获取IO引脚当前的延时设置
  154. * @return {FPinDelay} 当前的延时设置
  155. * @param {FPinIndex} pin IO引脚延时设置索引
  156. * @param {FPinDelayDir} dir 输入/输出延时
  157. * @param {FPinDelayType} type 精调/粗调延时
  158. */
  159. FPinDelay FPinGetDelay(const FPinIndex pin, FPinDelayDir dir, FPinDelayType type)
  160. {
  161. FIOCTRL_ASSERT_DELAY_REG_OFF(pin);
  162. u8 delay = 0;
  163. const u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  164. u32 delay_beg = 0, delay_end = 0;
  165. if (FPIN_OUTPUT_DELAY == dir)
  166. {
  167. delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off);
  168. }
  169. else if (FPIN_INPUT_DELAY == dir)
  170. {
  171. delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off);
  172. }
  173. else
  174. {
  175. FASSERT(0);
  176. }
  177. if (FPIN_DELAY_FINE_TUNING == type)
  178. {
  179. delay = FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg); /* bit[3:1] delicate delay tune */
  180. }
  181. else if (FPIN_DELAY_COARSE_TUNING == type)
  182. {
  183. delay = FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg); /* bit[6:4] rough delay adjust */
  184. }
  185. else
  186. {
  187. FASSERT(0);
  188. }
  189. FIOCTRL_ASSERT_DELAY(delay);
  190. return (FPinDelay)delay;
  191. }
  192. /**
  193. * @name: FPinGetDelayEn
  194. * @msg: 获取IO引脚当前的延时使能标志位
  195. * @return {*}
  196. * @param {FPinIndex} pin IO引脚延时设置索引
  197. * @param {FPinDelayDir} dir 输入/输出延时
  198. */
  199. boolean FPinGetDelayEn(const FPinIndex pin, FPinDelayDir dir)
  200. {
  201. FIOCTRL_ASSERT_DELAY_REG_OFF(pin);
  202. boolean enabled = FALSE;
  203. const u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  204. u32 delay_beg = 0, delay_end = 0;
  205. if (FPIN_OUTPUT_DELAY == dir)
  206. {
  207. delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off);
  208. }
  209. else if (FPIN_INPUT_DELAY == dir)
  210. {
  211. delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off);
  212. }
  213. else
  214. {
  215. FASSERT(0);
  216. }
  217. if (FIOCTRL_DELAY_EN(delay_beg) & reg_val)
  218. {
  219. enabled = TRUE;
  220. }
  221. return enabled;
  222. }
  223. /**
  224. * @name: FPinSetDelay
  225. * @msg: 设置IO引脚延时
  226. * @return {*}
  227. * @param {FPinIndex} pin IO引脚延时设置索引
  228. * @param {FPinDelayDir} dir 输入/输出延时
  229. * @param {FPinDelayType} type 精调/粗调延时
  230. * @param {FPinDelay} delay 延时档位设置 0 ~ 8 档可用
  231. */
  232. void FPinSetDelay(const FPinIndex pin, FPinDelayDir dir, FPinDelayType type, FPinDelay delay)
  233. {
  234. FIOCTRL_ASSERT_DELAY_REG_OFF(pin);
  235. FIOCTRL_ASSERT_DELAY(delay);
  236. u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  237. u32 delay_beg = 0, delay_end = 0;
  238. if (FPIN_OUTPUT_DELAY == dir)
  239. {
  240. delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off);
  241. }
  242. else if (FPIN_INPUT_DELAY == dir)
  243. {
  244. delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off);
  245. }
  246. else
  247. {
  248. FASSERT(0);
  249. }
  250. if (FPIN_DELAY_FINE_TUNING == type)
  251. {
  252. reg_val &= ~FIOCTRL_DELICATE_DELAY_MASK(delay_beg);
  253. delay = FIOCTRL_DELICATE_DELAY_GET(reg_val, delay_beg);
  254. }
  255. else if (FPIN_DELAY_COARSE_TUNING == type)
  256. {
  257. reg_val &= ~FIOCTRL_ROUGH_DELAY_MASK(delay_beg);
  258. delay = FIOCTRL_ROUGH_DELAY_GET(reg_val, delay_beg);
  259. }
  260. else
  261. {
  262. FASSERT(0);
  263. }
  264. FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val);
  265. return;
  266. }
  267. /**
  268. * @name: FPinSetDelayEn
  269. * @msg: 使能/去使能IO引脚延时
  270. * @return {*}
  271. * @param {FPinIndex} pin IO引脚延时设置索引
  272. * @param {FPinDelayDir} dir 输入/输出延时
  273. * @param {boolean} enable TRUE: 使能, FALSE: 去使能
  274. */
  275. void FPinSetDelayEn(const FPinIndex pin, FPinDelayDir dir, boolean enable)
  276. {
  277. FIOCTRL_ASSERT_DELAY_REG_OFF(pin);
  278. u32 reg_val = FtIn32(FIOCTRL_REG_BASE_ADDR + pin.reg_off);
  279. u32 delay_beg = 0, delay_end = 0;
  280. if (FPIN_OUTPUT_DELAY == dir)
  281. {
  282. delay_beg = FIOCTRL_DELAY_OUT_BEG_OFF(pin.reg_off);
  283. }
  284. else if (FPIN_INPUT_DELAY == dir)
  285. {
  286. delay_beg = FIOCTRL_DELAY_IN_BEG_OFF(pin.reg_off);
  287. }
  288. else
  289. {
  290. FASSERT(0);
  291. }
  292. reg_val &= ~FIOCTRL_DELAY_EN(delay_beg);
  293. if (enable)
  294. {
  295. reg_val |= FIOCTRL_DELAY_EN(delay_beg);
  296. }
  297. FtOut32(FIOCTRL_REG_BASE_ADDR + pin.reg_off, reg_val);
  298. return;
  299. }