!35 新增applications/204_hdf_i2c例程到master

Merge pull request !35 from 苏宗耀/master
This commit is contained in:
openharmony_sig_ci
2022-03-18 02:31:22 +00:00
committed by Gitee
4 changed files with 398 additions and 0 deletions
@@ -0,0 +1,29 @@
# Copyright (c) 2022 Talkweb Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//kernel/liteos_m/liteos.gni")
assert(defined(LOSCFG_DRIVERS_HDF_PLATFORM_I2C), "Must Config LOSCFG_DRIVERS_HDF_PLATFORM_I2C in kernel/liteos_m menuconfig!")
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
sources =[
"hdf_i2c_test.c",
]
include_dirs = [
".",
"//drivers/framework/include/platform",
"//drivers/framework/include/utils",
"//drivers/adapter/khdf/liteos_m/osal/include",
"//drivers/framework/include/osal",
]
}
+148
View File
@@ -0,0 +1,148 @@
# Niobe407开发板OpenHarmony基于HDF驱动框架编程开发——I2C
I2C是一种串行,同步,半双工通信协议,允许在同一总线上同时存在多个主机和从机。I2C总线由两条线组成:串行数据线(SDA)和串行时钟(SCL)。两条线都需要上拉电阻。I2C组件为设备提供读写等操作。
本示例将演示如何在Niobe407开发板上通过HDF驱动框架,使用I2C3接口对RJGT102芯片进行读写芯片UUID操作。
## 接口说明
```
1. I2C open打开I2C函数:DevHandle I2cOpen(int16_t number);
参数说明:
number: I2C控制器ID
return: 返回NULL,表示初始化成功
2. I2C close打开I2C函数:void I2cClose(DevHandle handle);
3. I2C transfer启动到I2C设备的自定义传输函数:int32_t I2cTransfer(DevHandle handle, struct I2cMsg *msgs, int16_t count);
参数说明:
handle: 指向通过{@link I2cOpen} 获得的I2C 控制器的设备句柄的指针
msgs: 指示指向 I2C 传输消息结构体数组的指针
count: 表示消息结构数组的长度
return: 返回传输的消息结构数,表示成功,返回负数,表示失败
```
## 编译调试
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
- 选择 `204_hdf_i2c`
- 在menuconfig的`(Top) → Driver`选项中使能如下配置:
```
[*] Enable Driver
[*] HDF driver framework support
[*] Enable HDF platform driver
[*] Enable HDF platform uart driver
```
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
### 运行结果
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志
```
Entering scheduler
[HDF:E/HDF_LOG_TAG]DeviceManagerStart in
[HDF:I/devmgr_service]start svcmgr result 0
[HDF:I/hcs_blob_if]CheckHcsBlobLength: the blobLength: 1248, byteAlign: 1
[HDF:D/device_node]node HDF_PLATFORM_I2C_MANAGER property empty, match attr:
[HDF:I/device_node]launch devnode HDF_PLATFORM_I2C_MANAGER
[HDF:I/i2c_core]I2cManagerBind: Enter!
[HDF:I/device_node]launch devnode HDF_PLATFORM_I2C_3
[HDF:I/i2c_core]I2cCntlrAdd: use default lock methods!
OHOS # hiview init success.
<--------------- OHOS Application Start Here --------------->
[HDF:E/HDF_LOG_TAG]into HdfI2cTestEntry!
write uuid success: [11, 22, 33, 44, aa, bb, cc, dd]
read uuid success: [11, 22, 33, 44, aa, bb, cc, dd]
```
## I2C HDF HCS配置文件解析
- device_i2c_info.hcs文件位于/device/board/talkweb/niobe407/sdk/hdf_config/device_i2c_info.hcs,本例子使用的是i2c3
```
root {
module = "talkweb,stm32f407";
device_info {
match_attr = "hdf_manager";
template host {
hostName = "";
priority = 100;
template device {
template deviceNode {
policy = 0;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "";
serviceName = "";
deviceMatchAttr = "";
}
}
}
platform :: host {
hostName = "platform_host";
priority = 0;
device_i2c :: device {
i2c_manager :: deviceNode {
policy = 2;
priority = 50;
moduleName = "HDF_PLATFORM_I2C_MANAGER";
serviceName = "HDF_PLATFORM_I2C_MANAGER";
}
i2c3 :: deviceNode {
policy = 0;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "HDF_I2C";
serviceName = "HDF_PLATFORM_I2C_3";
deviceMatchAttr = "i2c3_config";
}
}
}
}
}
```
- hdf_i2c.hcs文件位于/device/board/talkweb/niobe407/sdk/hdf_config/hdf_i2c.hcs,在此文件中配置串口对应的GPIO引脚信息,I2C配置信息
```
#include "device_i2c_info.hcs"
root {
platform {
i2c_config {
i2c3 {
gpio{
// 要配置的引脚个数,接下来的引脚名必须定义成gpio_num_1, gpio_num_2, gpio_num_3...
gpio_num_max = 2; //配置的GPIO个数
// port, pin, mode, speed, outputType, pull, alternate
gpio_num_1 = [7, 7, 2, 3, 1, 0, 4]; //GPIO配置1
gpio_num_2 = [7, 8, 2, 3, 1, 0, 4]; //GPIO配置2
}
driver : gpio {
match_attr = "i2c3_config";
port = 3; // I2C端口号(1~3)
dev_mode = 0; //0 = master, 1= slave
dev_addr = 0; //I2C 本机地址
speed = 100000; //I2C速率
}
}
}
}
}
```
## 关于I2C通讯测试芯片RJGT102
RJGT102芯片为一款标准I2C通讯的加密芯片。
这里将此芯片当成普通EEPROM使用,通过读写芯片内部UUID区域,以测试HDF I2C的基本收发功能。
具体芯片读写操作时序及寄存器信息,请自行参考数据手册
+217
View File
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2022 Talkweb Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cmsis_os2.h"
#include "i2c_if.h"
#include "los_compiler.h"
#include "los_task.h"
#include "ohos_run.h"
#include "samgr_lite.h"
#include <hdf_log.h>
#include <stdio.h>
#include <uart_if.h>
#define HDF_I2C_READ 1
#define HDF_I2C_WRITE 0
#define RJGT102_ADDR 0X68
#define RJGT_CMD_REGISTER_ADDR 0XB0
#define RJGT_MEM_REGISTER_ADDR 0XC0
#define RJGT_OBJ_REGISTER_ADDR 0XB2
#define RJGT_UUID_MEM_ADDR 0X90
#define RJGT_STATUS_REGISTER_ADDR 0XB3
#define RJGT_CMD_WRITE_UUID 0XAA
#define RJGT_CMD_READ_MEM 0X0F
static osThreadId_t g_i2cThreadId = NULL;
static DevHandle g_i2cHandle = NULL;
static int I2cWriteData(DevHandle handle, unsigned int devAddr, unsigned char *buffer, unsigned int length)
{
struct I2cMsg msg = {0};
msg.addr = devAddr;
msg.buf = buffer;
msg.len = length;
msg.flags = HDF_I2C_WRITE;
if (I2cTransfer(handle, &msg, 1) != 1) {
HDF_LOGE("[%s]: I2cWriteData fail \r\n", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int I2cReadData(DevHandle handle, unsigned int devAddr, unsigned char *buffer, unsigned int length)
{
I2cWriteData(handle, devAddr, buffer, 1);
struct I2cMsg msg = {0};
msg.addr = devAddr;
msg.buf = buffer;
msg.len = length;
msg.flags = HDF_I2C_READ;
if (I2cTransfer(handle, &msg, 1) != 1) {
HDF_LOGE("[%s]: I2cWriteData fail \r\n", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static void WriteRJGTCmdReg(unsigned char regVal)
{
unsigned char buffer[2] = {0};
buffer[0] = RJGT_CMD_REGISTER_ADDR;
buffer[1] = regVal;
I2cWriteData(g_i2cHandle, RJGT102_ADDR, buffer, 2);
}
static void WriteRJGTMemBuf(unsigned char *buf, unsigned int len)
{
unsigned char buffer[len + 1];
buffer[0] = RJGT_MEM_REGISTER_ADDR;
memcpy(&buffer[1], buf, len);
I2cWriteData(g_i2cHandle, RJGT102_ADDR, buffer, len + 1);
}
static void ReadRJGTMemBuf(unsigned char *buf, unsigned int len)
{
buf[0] = RJGT_MEM_REGISTER_ADDR;
I2cReadData(g_i2cHandle, RJGT102_ADDR, buf, len);
}
static unsigned char GetRJGTWriteStateReg(void)
{
unsigned char buffer[1] = {RJGT_STATUS_REGISTER_ADDR};
I2cReadData(g_i2cHandle, RJGT102_ADDR, buffer, 1);
return buffer[0];
}
static void WriteRJGTObjReg(unsigned char regVal)
{
unsigned char buffer[2] = {0};
buffer[0] = RJGT_OBJ_REGISTER_ADDR;
buffer[1] = regVal;
I2cWriteData(g_i2cHandle, RJGT102_ADDR, buffer, 2);
}
static bool Write8ByteUUID(unsigned char *buf)
{
WriteRJGTCmdReg(0X00);
WriteRJGTMemBuf(buf, 8);
WriteRJGTCmdReg(RJGT_CMD_WRITE_UUID);
osDelay(100);
int ret = GetRJGTWriteStateReg();
if (ret != 0X01) {
printf("Write8ByteUUID fail[%02X]\r\n", ret);
return false;
}
return true;
}
static bool Read8ByteUUID(unsigned char *buf)
{
WriteRJGTCmdReg(0X00);
WriteRJGTObjReg(RJGT_UUID_MEM_ADDR);
WriteRJGTCmdReg(RJGT_CMD_READ_MEM);
osDelay(100);
int ret = GetRJGTWriteStateReg();
if (ret != 0X01) {
printf("Read8ByteUUID fail[%02X]\r\n", ret);
return false;
}
ReadRJGTMemBuf(buf, 8);
return true;
}
static void exitThread(void)
{
if (g_i2cHandle != NULL) {
I2cClose(g_i2cHandle);
}
osThreadTerminate(g_i2cThreadId);
g_i2cThreadId = NULL;
}
static void *HdfI2cTestEntry(void *arg)
{
HDF_LOGE("into HdfI2cTestEntry!\n");
(void *)arg;
unsigned char ret = 0;
unsigned char busId = 3;
g_i2cHandle = I2cOpen(busId);
if (g_i2cHandle == NULL) {
HDF_LOGE("%s: Open I2c:%u fail!\r\n", __func__, busId);
exitThread();
return;
}
osDelay(100);
unsigned char uuidBuf[8] = {0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb, 0xcc, 0xdd};
if (Write8ByteUUID(uuidBuf) != true) {
exitThread();
return;
}
printf("write uuid success: [%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x]\r\n",
uuidBuf[0], uuidBuf[1], uuidBuf[2], uuidBuf[3], uuidBuf[4], uuidBuf[5], uuidBuf[6], uuidBuf[7]);
osDelay(100);
memset(uuidBuf, 0, sizeof(uuidBuf));
if (Read8ByteUUID(uuidBuf) != true) {
exitThread();
return;
}
printf("read uuid success: [%02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x]\r\n",
uuidBuf[0], uuidBuf[1], uuidBuf[2], uuidBuf[3], uuidBuf[4], uuidBuf[5], uuidBuf[6], uuidBuf[7]);
while (1) {
osDelay(1000);
}
}
void StartHdfI2cTest(void)
{
UINT32 uwRet;
UINT32 taskID;
TSK_INIT_PARAM_S stTask = {0};
stTask.pfnTaskEntry = (TSK_ENTRY_FUNC)HdfI2cTestEntry;
stTask.uwStackSize = 0X1000;
stTask.pcName = "HdfI2cTestEntry";
stTask.usTaskPrio = 2;
uwRet = LOS_TaskCreate(&taskID, &stTask);
if (uwRet != LOS_OK) {
printf("Task1 create failed\n");
}
}
OHOS_APP_RUN(StartHdfI2cTest);
@@ -52,6 +52,9 @@ choice APPLICATION_CHOOSE_NIOBE407
config NIOBE407_USE_203_HDF
bool
prompt "203_hdf_usart_read_write"
config NIOBE407_USE_204_HDF
bool
prompt "204_hdf_i2c"
config NIOBE407_USE_205_HDF
bool
prompt "205_hdf_watchdog"
@@ -97,6 +100,7 @@ config NIOBE407_APPLICATION_NAME
default "201_hdf_gpio_key" if NIOBE407_USE_201_HDF
default "202_hdf_spi_flash" if NIOBE407_USE_202_HDF
default "203_hdf_usart" if NIOBE407_USE_203_HDF
default "204_hdf_i2c" if NIOBE407_USE_204_HDF
default "205_hdf_watchdog" if NIOBE407_USE_205_HDF
default "206_hdf_pwm" if NIOBE407_USE_206_HDF
default "301_network_tcpclient" if NIOBE407_USE_301_NETWORK