Преглед на файлове

Merge pull request #1 from Guozhanxin/master

【添加】添加第一个版本的文件
朱天龙 (Armink) преди 7 години
родител
ревизия
dd2addae8f
променени са 5 файла, в които са добавени 338 реда и са изтрити 2 реда
  1. 82 2
      README.md
  2. 20 0
      SConscript
  3. 108 0
      pcf8574.c
  4. 82 0
      pcf8574.h
  5. 46 0
      pcf8574_sample.c

+ 82 - 2
README.md

@@ -1,2 +1,82 @@
-# pcf8574
-Remote 8-bit I/O expander for I2C-bus
+# pcf8574 软件包
+
+## 介绍
+
+`pcf8574` 软件包是 RT-Thread 针对 I2C 并行口扩展电路 PCF8574T 推出的一个软件包,兼容 PCF8574A。使用这个软件包,可以在 RT-Thread 上非常方便的使用该器件,并且支持一个 I2C 总线上挂载多个 PCF8574T。
+
+本文主要介绍该软件包的使用方式、API,以及 `MSH` 测试命令。
+
+### 目录结构
+
+```
+pcf8574
+│   README.md                       // 软件包说明
+│   pcf8574.c                       // 源文件
+│   pcf8574.h                       // 头文件
+│   pcf8574_sample.c                // 软件包使用示例代码
+│   SConscript                      // RT-Thread 默认的构建脚本
+│   LICENSE                         // 许可证文件
+```
+
+### 许可证
+
+pcf8574 遵循 Apache-2.0 许可,详见 `LICENSE` 文件。
+
+### 依赖
+
+- RT_Thread 3.0+
+- i2c 设备驱动
+
+## 获取方式
+
+使用 `pcf8574 package` 需要在 RT-Thread 的包管理中选中它,具体路径如下:
+
+```
+RT-Thread online packages
+    peripheral libraries and drivers  --->
+        pcf8574: Remote 8-bit I/O expander for I2C-bus  --->
+```
+
+进入 pcf8574 软件包的配置菜单按自己的需求进行具体的配置
+
+```
+    --- pcf8574: Remote 8-bit I/O expander for I2C-bus                           
+        [*]   Enable pcf8574 sample
+           Version (latest)  --->
+```
+
+**Enable pcf8574 sample** :开启 pcf8574  使用示例
+
+配置完成后让 RT-Thread 的包管理器自动更新,或者使用 pkgs --update 命令更新包到 BSP 中。
+
+## 使用方法
+
+pcf8574 软件包的使用流程一般如下:
+
+1. 初始化 pcf8574 设备 `pcf8574_init`
+2. 进行 IO 的操作
+   - 使用 API `pcf8574_port_read/pcf8574_port_write` 同时操作 8 路 IO
+   - 使用 API `pcf8574_pin_read/pcf8574_pin_write` 单独操作其中一 路 IO
+
+详细的使用方法可以参考[pcf8574 示例程序](pcf8574_sample.c) 。
+
+## MSH 测试命令
+
+如果开启了 pcf8574 软件包的示例程序,就会导出 `pcf8574_sample` 命令到控制台。调用之后默认会在 `i2c1`总线上探测地址为 `0x20` 的 PCF8574 设备,并会操作扩展端口的第 0 口进行测试。运行结果如下:
+
+```
+msh >pcf8574_sample
+[D/pcf8574] pcf8574 init done
+The value of pcf8574.P0 is 0
+The value of pcf8574.P0 is 1
+msh >
+```
+
+## 注意事项
+
+暂无。
+
+## 联系方式
+
+- 维护:[guozhanxin](https://github.com/Guozhanxin)
+- 主页:<https://github.com/RT-Thread-packages/pcf8574 >

+ 20 - 0
SConscript

@@ -0,0 +1,20 @@
+from building import *
+Import('rtconfig')
+
+src   = []
+cwd   = GetCurrentDir()
+
+# add pcf8574 src files.
+if GetDepend('PKG_USING_PCF8574'):
+    src += Glob('pcf8574.c')
+
+if GetDepend('PKG_USING_PCF8574_SAMPLE'):
+    src += Glob('pcf8574_sample.c')
+
+# add pcf8574 include path.
+path  = [cwd]
+
+# add src and include to group.
+group = DefineGroup('pcf8574', src, depend = ['PKG_USING_PCF8574'], CPPPATH = path)
+
+Return('group')

+ 108 - 0
pcf8574.c

@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-21     SummerGift   first version
+ * 2018-11-22     flybreak     Make the first version of pcf8574's package
+ */
+
+#include "pcf8574.h"
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME     "pcf8574"
+#define DBG_LEVEL            DBG_INFO
+#define DBG_COLOR
+#include <rtdbg.h>
+
+uint8_t pcf8574_port_read(pcf8574_device_t dev)
+{
+    uint8_t value;
+
+    rt_device_read(&dev->bus->parent, dev->i2c_addr, &value, 1);
+
+    return value;
+}
+
+void pcf8574_port_write(pcf8574_device_t dev, uint8_t value)
+{
+    rt_device_write(&dev->bus->parent, dev->i2c_addr, &value, 1);
+}
+
+uint8_t pcf8574_pin_read(pcf8574_device_t dev, uint8_t bit)
+{
+    uint8_t data;
+    data = pcf8574_port_read(dev);
+
+    if (data & (1 << bit))
+        return 1;
+    else
+        return 0;
+}
+
+void pcf8574_pin_write(pcf8574_device_t dev, uint8_t bit, uint8_t value)
+{
+    uint8_t data;
+    data = pcf8574_port_read(dev);
+
+    if (value == 0)
+        data &= ~(1 << bit);
+    else 
+        data |= 1 << bit;
+
+    pcf8574_port_write(dev, data);
+}
+
+pcf8574_device_t pcf8574_init(const char *dev_name, rt_uint8_t i2c_addr)
+{
+    uint8_t buffer[] = { 0xFF };
+    pcf8574_device_t dev = RT_NULL;
+    
+    RT_ASSERT(dev_name);
+
+    dev = rt_calloc(1, sizeof(struct pcf8574_device));
+    if (dev == RT_NULL)
+    {
+        LOG_E("Can't allocate memory for pcf8574 device on '%s' ", dev_name);
+        goto __exit;
+    }
+
+    dev->bus = (struct rt_i2c_bus_device *)rt_device_find(dev_name);
+    if (dev->bus == RT_NULL)
+    {
+        LOG_E("i2c_bus %s for PCF8574 not found!", dev_name);
+        goto __exit;
+    }
+
+    if (i2c_addr != RT_NULL)
+        dev->i2c_addr = i2c_addr;
+    else
+        dev->i2c_addr = PCF8574_ADDR_DEFAULT;
+
+    if (rt_device_open(&dev->bus->parent, RT_NULL) != RT_EOK)
+    {
+        LOG_D("i2c_bus %s for PCF8574 opened failed!", dev_name);
+        goto __exit;
+    }
+
+    rt_device_write(&dev->bus->parent, dev->i2c_addr, &buffer, 1);
+
+    LOG_D("pcf8574 init done", dev_name);
+    return dev;
+
+__exit:
+    if (dev != RT_NULL)
+        rt_free(dev);
+
+    return RT_NULL;
+}
+
+void pcf8574_deinit(struct pcf8574_device *dev)
+{
+    RT_ASSERT(dev);
+
+    rt_free(dev);
+}

+ 82 - 0
pcf8574.h

@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-21     SummerGift   first version
+ * 2018-11-22     flybreak     Make the first version of pcf8574's package
+ */
+
+#ifndef __PCF8574_H
+#define __PCF8574_H
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define PCF8574_ADDR_DEFAULT    0x20
+
+/* pcf8574 device structure */
+struct pcf8574_device
+{
+    struct rt_i2c_bus_device *bus;
+    rt_uint8_t i2c_addr;
+};
+typedef struct pcf8574_device *pcf8574_device_t;
+
+/**
+ * This function initialize the pcf8574 device.
+ *
+ * @param dev_name the name of i2c bus device
+ * @param i2c_addr the i2c device address for i2c communication,RT_NULL use default address
+ *
+ * @return the pointer of device structure, RT_NULL reprensents  initialization failed.
+ */
+pcf8574_device_t pcf8574_init(const char *dev_name, rt_uint8_t i2c_addr);
+
+/**
+ * This function releases memory
+ *
+ * @param dev the pointer of device structure
+ */
+void pcf8574_deinit(struct pcf8574_device *dev);
+
+/**
+ * This function read the data port of pcf8574.
+ *
+ * @param dev the pointer of device structure
+ *
+ * @return the state of data port. 0xFF meas all pin is high.
+ */
+uint8_t pcf8574_port_read(pcf8574_device_t dev);
+
+/**
+ * This function sets the status of the data port.
+ *
+ * @param dev the pointer of device structure
+ * @param port_val the port value you want to set, 0xFF meas all pin output high.
+ */
+void pcf8574_port_write(pcf8574_device_t dev, uint8_t port_val);
+
+/**
+ * This function read the specified port pin of the pcf8574.
+ *
+ * @param dev the pointer of device structure
+ * @param pin the specified pin of the data port
+ *
+ * @return the status of the specified data port pin, 0 is low, 1 is high.
+ */
+uint8_t pcf8574_pin_read(pcf8574_device_t dev, uint8_t pin);
+
+/**
+ * This function sets the status of the specified port pin.
+ *
+ * @param dev the pointer of device structure
+ * @param pin_val the specified pin value you want to set, 0 is low, 1 is high.
+ */
+void pcf8574_pin_write(pcf8574_device_t dev, uint8_t pin, uint8_t pin_val);
+
+#endif
+

+ 46 - 0
pcf8574_sample.c

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-22     flybreak     Make the first version of pcf8574's package
+ */
+
+#include <rtthread.h>
+#include "pcf8574.h"
+
+#define TEST_IO    0 //(0-7)
+#define I2C_BUS    "i2c1"
+
+int pcf8574_sample(void)
+{
+    rt_uint8_t value;
+    pcf8574_device_t dev = RT_NULL;
+    
+    dev = pcf8574_init(I2C_BUS, RT_NULL);
+
+    if (dev == RT_NULL)
+        return -1;
+
+    pcf8574_pin_write(dev, TEST_IO, 0);
+
+    value = pcf8574_pin_read(dev, TEST_IO);
+    rt_kprintf("The value of pcf8574.P%d is %d\n", TEST_IO, value);
+
+    rt_thread_mdelay(1000);
+
+    pcf8574_pin_write(dev, TEST_IO, 1);
+
+    value = pcf8574_pin_read(dev, TEST_IO);
+    rt_kprintf("The value of pcf8574.P%d is %d\n", TEST_IO, value);
+
+    pcf8574_deinit(dev);
+
+    return 0;
+}
+#ifdef FINSH_USING_MSH
+MSH_CMD_EXPORT(pcf8574_sample, a pcf8574 sample);
+#endif