fi2c.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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: fi2c.c
  15. * Date: 2022-02-10 14:53:42
  16. * LastEditTime: 2022-02-18 08:36:58
  17. * Description:  This files is for
  18. *
  19. * Modify History:
  20. * Ver   Who        Date         Changes
  21. * ----- ------     --------    --------------------------------------
  22. */
  23. /***************************** Include Files *********************************/
  24. #include <string.h>
  25. #include "fio.h"
  26. #include "ferror_code.h"
  27. #include "ftypes.h"
  28. #include "fdebug.h"
  29. #include "fi2c_hw.h"
  30. #include "fi2c.h"
  31. /************************** Constant Definitions *****************************/
  32. /**************************** Type Definitions *******************************/
  33. /***************** Macros (Inline Functions) Definitions *********************/
  34. #define FI2C_DEBUG_TAG "I2C"
  35. #define FI2C_ERROR(format, ...) FT_DEBUG_PRINT_E(FI2C_DEBUG_TAG, format, ##__VA_ARGS__)
  36. #define FI2C_INFO(format, ...) FT_DEBUG_PRINT_I(FI2C_DEBUG_TAG, format, ##__VA_ARGS__)
  37. #define FI2C_DEBUG(format, ...) FT_DEBUG_PRINT_D(FI2C_DEBUG_TAG, format, ##__VA_ARGS__)
  38. /************************** Function Prototypes ******************************/
  39. static FError FI2cReset(FI2c *instance_p);
  40. /************************** Variable Definitions *****************************/
  41. static const char *FI2C_ERROR_CODE_MSG[FI2C_NUM_OF_ERR_CODE] =
  42. {
  43. "FI2C_SUCCESS : fi2c success",
  44. "FI2C_ERR_INVAL_PARM : fi2c invalid input parameters",
  45. "FI2C_ERR_NOT_READY : fi2c driver not ready",
  46. "FI2C_ERR_TIMEOUT : fi2c wait timeout",
  47. "FI2C_ERR_NOT_SUPPORT : fi2c non support operation",
  48. "FI2C_ERR_INVAL_STATE : fi2c invalid state"
  49. };
  50. /*****************************************************************************/
  51. /* 此文件主要为了完成用户对外接口,用户可以使用这些接口直接开始工作 */
  52. /* - 包括用户API的定义和实现
  53. - 同时包含必要的OPTION方法,方便用户进行配置
  54. - 如果驱动可以直接进行I/O操作,在此源文件下可以将API 进行实现 */
  55. /**
  56. * @name: FI2cCfgInitialize
  57. * @msg: 完成I2C驱动实例的初始化,使之可以使用
  58. * @param {FI2c} *instance_p I2C驱动实例数据
  59. * @param {FI2cConfig} *cofig_p I2C驱动配置数据
  60. * @return SUCCESS if initialization was successful
  61. * ERROR
  62. */
  63. FError FI2cCfgInitialize(FI2c *instance_p, const FI2cConfig *input_config_p)
  64. {
  65. FASSERT(instance_p && input_config_p);
  66. FError ret = FI2C_SUCCESS;
  67. /*
  68. * If the device is started, disallow the initialize and return a Status
  69. * indicating it is started. This allows the user to de-initialize the device
  70. * and reinitialize, but prevents a user from inadvertently
  71. * initializing.
  72. */
  73. if (FT_COMPONENT_IS_READY == instance_p->is_ready)
  74. {
  75. FI2C_ERROR("device is already initialized!!!");
  76. return FI2C_ERR_INVAL_STATE;
  77. }
  78. /*
  79. * Set default values and configuration data, including setting the
  80. * callback handlers to stubs so the system will not crash should the
  81. * application not assign its own callbacks.
  82. */
  83. FI2cDeInitialize(instance_p);
  84. instance_p->config = *input_config_p;
  85. /*
  86. * Reset the device.
  87. */
  88. ret = FI2cReset(instance_p);
  89. if (FI2C_SUCCESS == ret)
  90. {
  91. instance_p->is_ready = FT_COMPONENT_IS_READY;
  92. }
  93. return ret;
  94. }
  95. /**
  96. * @name: FI2cDeInitialize
  97. * @msg: 完成I2C驱动实例去使能,清零实例数据
  98. * @return {*}
  99. * @param {FI2c} *instance_p
  100. */
  101. void FI2cDeInitialize(FI2c *instance_p)
  102. {
  103. FASSERT(instance_p);
  104. instance_p->is_ready = 0;
  105. memset(instance_p, 0, sizeof(*instance_p));
  106. }
  107. /**
  108. * @name: FI2cReset
  109. * @msg: 重置I2C控制器
  110. * @return {*}
  111. * @param {FI2c} *instance_p, I2C驱动实例数据
  112. */
  113. static FError FI2cReset(FI2c *instance_p)
  114. {
  115. FASSERT(instance_p);
  116. FError ret = FI2C_SUCCESS;
  117. FI2cConfig *config_p = &instance_p->config;
  118. uintptr base_addr = config_p->base_addr;
  119. u32 reg_val = 0;
  120. ret = FI2cSetEnable(base_addr, FALSE); /* disable i2c ctrl */
  121. if (FI2C_MASTER == config_p->work_mode)
  122. {
  123. reg_val |= (config_p->use_7bit_addr) ? FI2C_CON_MASTER_ADR_7BIT : FI2C_CON_MASTER_ADR_10BIT ;
  124. reg_val |= FI2C_CON_SLAVE_DISABLE;
  125. reg_val |= FI2C_CON_MASTER_MODE;
  126. reg_val |= FI2C_CON_RESTART_EN;
  127. }
  128. else
  129. {
  130. reg_val |= (config_p->use_7bit_addr) ? FI2C_CON_SLAVE_ADR_7BIT : FI2C_CON_SLAVE_ADR_10BIT;
  131. reg_val &= (~FI2C_CON_MASTER_MODE);
  132. reg_val |= FI2C_CON_SLAVE_MODE;
  133. }
  134. reg_val |= FI2C_CON_STD_SPEED;
  135. FI2C_WRITE_REG32(base_addr, FI2C_CON_OFFSET, reg_val);
  136. FI2C_WRITE_REG32(base_addr, FI2C_RX_TL_OFFSET, 0);
  137. FI2C_WRITE_REG32(base_addr, FI2C_TX_TL_OFFSET, 0);
  138. FI2C_SET_INTRRUPT_MASK(base_addr, 0); /* disable all intr */
  139. ret = FI2cSetSpeed(base_addr, config_p->speed_rate);
  140. if (FI2C_SUCCESS == ret)
  141. ret = FI2cSetEnable(base_addr, TRUE); /* enable i2c ctrl */
  142. /* if init successed, and i2c is in slave mode, set slave address */
  143. if ((FI2C_SUCCESS == ret) && (FI2C_SLAVE == config_p->work_mode))
  144. ret = FI2cSetSar(base_addr, config_p->slave_addr);
  145. return ret;
  146. }
  147. /**
  148. * @name: FI2cErrorToMessage
  149. * @msg: 获取I2C模块错误码对应的错误信息
  150. * @return {const char *}, 错误码信息,NULL表示失败
  151. * @param {FError} error, I2C输入错误码
  152. */
  153. const char *FI2cErrorToMessage(FError error)
  154. {
  155. const char *msg = NULL;
  156. if (FI2C_SUCCESS != error && (FI2C_ERR_CODE_PREFIX != error & (FT_ERRCODE_SYS_MODULE_MASK | FT_ERRCODE_SUB_MODULE_MASK)))
  157. {
  158. /* if input error do not belong to this module */
  159. return msg;
  160. }
  161. u32 index = error & FT_ERRCODE_TAIL_VALUE_MASK;
  162. if (index < FI2C_NUM_OF_ERR_CODE)
  163. {
  164. msg = FI2C_ERROR_CODE_MSG[index];
  165. }
  166. return msg;
  167. }