test_pfc8563_i2c.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-12-30 CDT first version
  9. */
  10. /*
  11. * 程序清单:这是一个 I2C 设备使用例程
  12. * 例程导出了 pcf8563 命令到控制终端
  13. * 命令调用格式:i2c_pcf8563_sample i2c1
  14. * 命令解释:命令第二个参数是要使用的I2C总线设备名称,为空则使用默认的I2C总线设备
  15. * 程序功能:通过 I2C 设备读取时间信息并打印
  16. */
  17. #include <rtthread.h>
  18. #include <rtdevice.h>
  19. #if defined(BSP_USING_I2C)
  20. #define PFC8563_I2C_BUS_NAME "i2c1" /* I2C总线设备名称 */
  21. #define PFC8563_ADDR 0x51 /* 从机地址 */
  22. #define PFC8563_REG_SEC 0x02 /* 校准命令 */
  23. #define PFC8563_REG_CTRL_SR1 0x00 /* 校准命令 */
  24. #define PFC8563_TIME_LEN 0x7 /* 获取数据长度 */
  25. #define RTC_DEC2BCD(__DATA__) ((((__DATA__) / 10U) << 4U) + ((__DATA__) % 10U))
  26. #define RTC_BCD2DEC(__DATA__) ((((__DATA__) >> 4U) * 10U) + ((__DATA__) & 0x0FU))
  27. static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */
  28. static rt_bool_t initialized = RT_FALSE; /* 传感器初始化状态 */
  29. /* 写传感器寄存器 */
  30. static rt_err_t write_regs(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data, rt_uint8_t len)
  31. {
  32. rt_uint8_t buf[16 + 1];
  33. struct rt_i2c_msg msgs;
  34. rt_uint32_t buf_size = 1;
  35. buf[0] = reg; // cmd
  36. if (data != RT_NULL)
  37. {
  38. memcpy(&buf[1], data, len);
  39. buf_size += len;
  40. }
  41. msgs.addr = PFC8563_ADDR;
  42. msgs.flags = RT_I2C_WR;
  43. msgs.buf = buf;
  44. msgs.len = buf_size;
  45. /* 调用I2C设备接口传输数据 */
  46. if (rt_i2c_transfer(bus, &msgs, 1) == 1)
  47. {
  48. return RT_EOK;
  49. }
  50. else
  51. {
  52. rt_kprintf("write regs failed!\n");
  53. return -RT_ERROR;
  54. }
  55. }
  56. /* 读传感器寄存器数据 */
  57. static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data, rt_uint8_t len)
  58. {
  59. struct rt_i2c_msg msgs[2];
  60. rt_uint8_t buf[16 + 1];
  61. rt_uint32_t buf_size = 1;
  62. buf[0] = reg; // cmd
  63. msgs[0].addr = PFC8563_ADDR;
  64. msgs[0].flags = RT_I2C_WR;
  65. msgs[0].buf = buf;
  66. msgs[0].len = buf_size;
  67. msgs[1].addr = PFC8563_ADDR;
  68. msgs[1].flags = RT_I2C_RD;
  69. msgs[1].buf = data;
  70. msgs[1].len = len;
  71. /* 调用I2C设备接口传输数据 */
  72. if (rt_i2c_transfer(bus, &msgs[0], 2) == 2)
  73. {
  74. return RT_EOK;
  75. }
  76. else
  77. {
  78. rt_kprintf("read regs failed!\n");
  79. return -RT_ERROR;
  80. }
  81. }
  82. static void pcf8563_init(const char *name)
  83. {
  84. rt_uint8_t temp[16];
  85. /* 查找I2C总线设备,获取I2C总线设备句柄 */
  86. i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
  87. if (i2c_bus == RT_NULL)
  88. {
  89. rt_kprintf("can't find %s device!\n", name);
  90. }
  91. else
  92. {
  93. rt_thread_mdelay(500);
  94. temp[0] = 0x28U;
  95. write_regs(i2c_bus, PFC8563_REG_CTRL_SR1, temp, 1);
  96. rt_thread_mdelay(100);
  97. temp[0] = 0x08U;
  98. write_regs(i2c_bus, PFC8563_REG_CTRL_SR1, temp, 1);
  99. rt_thread_mdelay(100);
  100. temp[0] = RTC_DEC2BCD(55);
  101. temp[1] = RTC_DEC2BCD(59);
  102. temp[2] = RTC_DEC2BCD(23);
  103. temp[3] = RTC_DEC2BCD(1);
  104. temp[4] = RTC_DEC2BCD(3);
  105. temp[5] = RTC_DEC2BCD(1);
  106. temp[6] = RTC_DEC2BCD(20);
  107. write_regs(i2c_bus, PFC8563_REG_SEC, temp, PFC8563_TIME_LEN);
  108. rt_thread_mdelay(100);
  109. initialized = RT_TRUE;
  110. }
  111. }
  112. static void serial_thread_entry(void *parameter)
  113. {
  114. rt_uint8_t time[16];
  115. memset(time, 0, 16);
  116. rt_thread_mdelay(500);
  117. rt_thread_mdelay(500);
  118. while (1)
  119. {
  120. // if (RT_EOK == read_regs(i2c_bus, PFC8563_REG_SEC, time, PFC8563_TIME_LEN))
  121. if (RT_EOK == read_regs(i2c_bus, PFC8563_REG_SEC, time, 1))
  122. {
  123. time[0] &= 0x7FU;
  124. time[1] &= 0x7FU;
  125. time[2] &= 0x3FU;
  126. time[3] &= 0x3FU;
  127. time[4] &= 0x7U;
  128. time[5] &= 0x1FU;
  129. time[6] &= 0xFFU;
  130. /* Print current date and time */
  131. rt_kprintf("Time: 20%02d/%02d/%02d %02d:%02d:%02d\n", RTC_BCD2DEC(time[6]), RTC_BCD2DEC(time[5]),
  132. RTC_BCD2DEC(time[3]), RTC_BCD2DEC(time[2]), RTC_BCD2DEC(time[1]), RTC_BCD2DEC(time[0]));
  133. }
  134. else
  135. {
  136. rt_kprintf("Get time failed!\n");
  137. }
  138. rt_thread_mdelay(100);
  139. }
  140. }
  141. void i2c_pcf8563_sample(int argc, char *argv[])
  142. {
  143. char bus_name[RT_NAME_MAX];
  144. if (argc == 2)
  145. {
  146. rt_strncpy(bus_name, argv[1], RT_NAME_MAX);
  147. }
  148. else
  149. {
  150. rt_strncpy(bus_name, PFC8563_I2C_BUS_NAME, RT_NAME_MAX);
  151. }
  152. if (!initialized)
  153. {
  154. /* 传感器初始化 */
  155. pcf8563_init(bus_name);
  156. }
  157. if (initialized)
  158. {
  159. /* 创建 serial 线程 */
  160. rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
  161. /* 创建成功则启动线程 */
  162. if (thread != RT_NULL)
  163. {
  164. rt_thread_startup(thread);
  165. }
  166. else
  167. {
  168. rt_kprintf("startup thread failed!\n");
  169. }
  170. }
  171. else
  172. {
  173. rt_kprintf("initialize sensor failed!\n");
  174. }
  175. }
  176. /* 导出到 msh 命令列表中 */
  177. MSH_CMD_EXPORT(i2c_pcf8563_sample, i2c aht10 sample);
  178. #endif