!538 add niobe407 board hdf drivers under adapter and add the niobe407 visibility in hdf_hcs.gni

Merge pull request !538 from 龙幸开/niobehdf
This commit is contained in:
openharmony_ci
2022-04-11 02:59:05 +00:00
committed by Gitee
14 changed files with 3538 additions and 3 deletions
+4
View File
@@ -83,4 +83,8 @@ hdf_driver("hdf_core") {
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/fnlink/shields" ]
}
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
Executable → Regular
+1
View File
@@ -98,5 +98,6 @@ set_defaults("hdf_driver") {
configs = [ "$HDFTOPDIR:hdf_config" ]
visibility = [ "$HDFTOPDIR:*" ]
visibility += [ "//device/soc/bestechnic/bes2600/liteos_m/*" ]
visibility += [ "//device/board/talkweb/niobe407/liteos_m/*" ]
visibility += [ "//drivers/adapter/*" ]
}
+7
View File
@@ -25,10 +25,17 @@ hdf_driver(module_name) {
if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) {
sources += [ "gpio_wm.c" ]
}
if (defined(LOSCFG_SOC_SERIES_STM32F4xx)) {
sources += [ "gpio_stm32f4xx.c" ]
}
include_dirs = [ "." ]
if (defined(LOSCFG_SHIELD_V200ZR_EVB_T1) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/fnlink/shields" ]
}
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
+604
View File
@@ -0,0 +1,604 @@
/*
* Copyright (c) 2022 Talkweb Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include <stdlib.h>
#include "hal_gpio.h"
#include "hal_exti.h"
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#include "hcs_macro.h"
#include "hdf_config_macro.h"
#else
#include "device_resource_if.h"
#endif
#include "gpio_core.h"
#include "hdf_log.h"
#include "osal_irq.h"
#define HDF_LOG_TAG gpio_stm_c
static const uint16_t g_stmRealPinMaps[STM32_GPIO_PIN_MAX] = {
LL_GPIO_PIN_0,
LL_GPIO_PIN_1,
LL_GPIO_PIN_2,
LL_GPIO_PIN_3,
LL_GPIO_PIN_4,
LL_GPIO_PIN_5,
LL_GPIO_PIN_6,
LL_GPIO_PIN_7,
LL_GPIO_PIN_8,
LL_GPIO_PIN_9,
LL_GPIO_PIN_10,
LL_GPIO_PIN_11,
LL_GPIO_PIN_12,
LL_GPIO_PIN_13,
LL_GPIO_PIN_14,
LL_GPIO_PIN_15,
};
typedef struct {
uint32_t group;
uint32_t realPin;
uint32_t pin;
} GpioInflectInfo;
GpioInflectInfo g_gpioPinsMap[STM32_GPIO_PIN_MAX * STM32_GPIO_GROUP_MAX] = {0};
static const GPIO_TypeDef* g_gpioxMaps[STM32_GPIO_GROUP_MAX] = {
GPIOA,
GPIOB,
GPIOC,
GPIOD,
GPIOE,
GPIOF,
GPIOG,
GPIOH,
GPIOI,
};
static const uint32_t g_gpioExitLineMap[STM32_GPIO_PIN_MAX] = {
LL_EXTI_LINE_0,
LL_EXTI_LINE_1,
LL_EXTI_LINE_2,
LL_EXTI_LINE_3,
LL_EXTI_LINE_4,
LL_EXTI_LINE_5,
LL_EXTI_LINE_6,
LL_EXTI_LINE_7,
LL_EXTI_LINE_8,
LL_EXTI_LINE_9,
LL_EXTI_LINE_10,
LL_EXTI_LINE_11,
LL_EXTI_LINE_12,
LL_EXTI_LINE_13,
LL_EXTI_LINE_14,
LL_EXTI_LINE_15,
};
typedef struct {
uint32_t pin;
uint32_t realPin;
uint32_t mode;
uint32_t group;
uint32_t pull;
uint32_t speed;
uint32_t outputType;
uint32_t alternate;
} GpioResource;
enum GpioDeviceState {
GPIO_DEVICE_UNINITIALIZED = 0x0u,
GPIO_DEVICE_INITIALIZED = 0x1u,
};
typedef struct {
uint32_t pinNums;
GpioResource resource;
STM32_GPIO_GROUP group; /* gpio config */
} GpioDevice;
static struct GpioCntlr g_stmGpioCntlr;
static HAL_GPIO_EXIT_CFG_T g_gpioExitCfg[STM32_GPIO_PIN_MAX * STM32_GPIO_GROUP_MAX] = {0};
static void OemGpioIrqHdl(uint32_t pin)
{
GpioCntlrIrqCallback(&g_stmGpioCntlr, pin);
return;
}
/* HdfDriverEntry method definitions */
static int32_t GpioDriverInit(struct HdfDeviceObject *device);
static void GpioDriverRelease(struct HdfDeviceObject *device);
/* HdfDriverEntry definitions */
struct HdfDriverEntry g_GpioDriverEntry = {
.moduleVersion = 1,
.moduleName = "ST_GPIO_MODULE_HDF",
.Init = GpioDriverInit,
.Release = GpioDriverRelease,
};
HDF_INIT(g_GpioDriverEntry);
/* GpioMethod method definitions */
static int32_t GpioDevWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val);
static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val);
static int32_t GpioDevSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir);
static int32_t GpioDevGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir);
static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode);
static int32_t GpioDevUnSetIrq(struct GpioCntlr *cntlr, uint16_t gpio);
static int32_t GpioDevEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio);
static int32_t GpioDevDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio);
/* GpioMethod definitions */
struct GpioMethod g_GpioCntlrMethod = {
.request = NULL,
.release = NULL,
.write = GpioDevWrite,
.read = GpioDevRead,
.setDir = GpioDevSetDir,
.getDir = GpioDevGetDir,
.toIrq = NULL,
.setIrq = GpioDevSetIrq,
.unsetIrq = GpioDevUnSetIrq,
.enableIrq = GpioDevEnableIrq,
.disableIrq = GpioDevDisableIrq,
};
static void InitGpioClock(STM32_GPIO_GROUP group)
{
switch (group) {
case STM32_GPIO_GROUP_A:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
break;
case STM32_GPIO_GROUP_B:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
break;
case STM32_GPIO_GROUP_C:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
break;
case STM32_GPIO_GROUP_D:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD);
break;
case STM32_GPIO_GROUP_E:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOE);
break;
case STM32_GPIO_GROUP_F:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOF);
break;
case STM32_GPIO_GROUP_G:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOG);
break;
case STM32_GPIO_GROUP_H:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOH);
break;
case STM32_GPIO_GROUP_I:
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOI);
break;
default:
break;
}
}
static int32_t InitGpioDevice(GpioDevice* device)
{
LL_GPIO_InitTypeDef gpioInitStruct = {0};
if (device == NULL) {
HDF_LOGE("%s: device is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
uint32_t halGpio = g_stmRealPinMaps[device->resource.realPin];
if (halGpio > LL_GPIO_PIN_15 || halGpio < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, halGpio);
return HDF_ERR_NOT_SUPPORT;
}
/* init clock */
InitGpioClock(device->resource.group);
GPIO_TypeDef* goiox = g_gpioxMaps[device->resource.group];
if (device->resource.mode & LL_GPIO_MODE_OUTPUT) {
LL_GPIO_ResetOutputPin(goiox, halGpio);
}
gpioInitStruct.Pin = halGpio;
gpioInitStruct.Mode = device->resource.mode;
gpioInitStruct.Pull = device->resource.pull;
gpioInitStruct.Speed = device->resource.speed;
gpioInitStruct.OutputType = device->resource.outputType;
gpioInitStruct.Alternate = device->resource.alternate;
LL_GPIO_Init(goiox, &gpioInitStruct);
return HDF_SUCCESS;
}
#ifndef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
static int32_t GpioParseHcs(const struct DeviceResourceIface *dri,
GpioDevice *device, const struct DeviceResourceNode *resourceNode)
{
GpioResource *resource = NULL;
resource = &device->resource;
if (resource == NULL) {
HDF_LOGE("%s: resource is NULL", __func__);
return HDF_ERR_INVALID_OBJECT;
}
if (dri->GetUint32(resourceNode, "pinNum", &device->pinNums, 0) != HDF_SUCCESS) {
HDF_LOGE("gpio config read pinNum fail");
return HDF_FAILURE;
}
for (size_t i = 0; i < device->pinNums; i++) {
if (dri->GetUint32ArrayElem(resourceNode, "pin", i, &resource->pin, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "realPin", i, &resource->realPin, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "mode", i, &resource->mode, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "speed", i, &resource->speed, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "pull", i, &resource->pull, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "output", i, &resource->outputType, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "group", i, &resource->group, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
if (dri->GetUint32ArrayElem(resourceNode, "alternate", i, &resource->alternate, 0) != HDF_SUCCESS) {
return HDF_FAILURE;
}
g_gpioPinsMap[resource->pin].group = resource->group;
g_gpioPinsMap[resource->pin].realPin = resource->realPin;
g_gpioPinsMap[resource->pin].pin = resource->pin;
if (InitGpioDevice(device) != HDF_SUCCESS) {
HDF_LOGE("InitGpioDevice FAIL\r\n");
return HDF_FAILURE;
}
}
return HDF_SUCCESS;
}
#endif
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#define PLATFORM_GPIO_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), gpio_config)
static uint32_t GetGpioDeviceResource(GpioDevice *device)
{
uint32_t relPin;
int32_t ret;
GpioResource *resource = NULL;
if (device == NULL) {
HDF_LOGE("%s: device is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
resource = &device->resource;
if (resource == NULL) {
HDF_LOGE("%s: resource is NULL", __func__);
return HDF_ERR_INVALID_OBJECT;
}
device->pinNums = HCS_PROP(PLATFORM_GPIO_CONFIG, pinNum);
uint32_t pins[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, pin));
uint32_t realPins[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, realPin));
uint32_t groups[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, group));
uint32_t modes[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, mode));
uint32_t speeds[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, speed));
uint32_t pulls[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, pull));
uint32_t outputs[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, output));
uint32_t alternates[] = HCS_ARRAYS(HCS_NODE(PLATFORM_GPIO_CONFIG, alternate));
for (size_t i = 0; i < device->pinNums; i++) {
resource->pin = pins[i];
resource->realPin = realPins[i];
resource->group = groups[i];
resource->mode = modes[i];
resource->speed = speeds[i];
resource->pull = pulls[i];
resource->outputType = outputs[i];
resource->alternate = alternates[i];
g_gpioPinsMap[resource->pin].group = resource->group;
g_gpioPinsMap[resource->pin].realPin = resource->realPin;
g_gpioPinsMap[resource->pin].pin = resource->pin;
if (InitGpioDevice(device) != HDF_SUCCESS) {
HDF_LOGE("InitGpioDevice FAIL\r\n");
return HDF_FAILURE;
}
}
return HDF_SUCCESS;
}
#else
static int32_t GetGpioDeviceResource(GpioDevice *device, const struct DeviceResourceNode *resourceNode)
{
int32_t ret;
struct DeviceResourceIface *dri = NULL;
if (device == NULL || resourceNode == NULL) {
HDF_LOGE("%s: device is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
if (dri == NULL || dri->GetUint32 == NULL) {
HDF_LOGE("DeviceResourceIface is invalid");
return HDF_ERR_INVALID_OBJECT;
}
if (GpioParseHcs(dri, device, resourceNode) != HDF_SUCCESS) {
HDF_LOGE("gpio config parse hcs fail");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
#endif
static int32_t AttachGpioDevice(struct GpioCntlr *gpioCntlr, struct HdfDeviceObject *device)
{
int32_t ret;
GpioDevice *gpioDevice = NULL;
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
if (device == NULL) {
#else
if (device == NULL || device->property == NULL) {
#endif
HDF_LOGE("%s: property is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
gpioDevice = (GpioDevice *)OsalMemAlloc(sizeof(GpioDevice));
if (gpioDevice == NULL) {
HDF_LOGE("%s: OsalMemAlloc gpioDevice error", __func__);
return HDF_ERR_MALLOC_FAIL;
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
ret = GetGpioDeviceResource(gpioDevice);
#else
ret = GetGpioDeviceResource(gpioDevice, device->property);
#endif
if (ret != HDF_SUCCESS) {
(void)OsalMemFree(gpioDevice);
return HDF_FAILURE;
}
gpioCntlr->priv = gpioDevice;
gpioCntlr->count = gpioDevice->pinNums;
return HDF_SUCCESS;
}
static int32_t GpioDriverInit(struct HdfDeviceObject *device)
{
int32_t ret;
struct GpioCntlr *gpioCntlr = NULL;
if (device == NULL) {
HDF_LOGE("%s: device is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
ret = PlatformDeviceBind(&g_stmGpioCntlr.device, device);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: bind hdf device failed:%d", __func__, ret);
return ret;
}
gpioCntlr = GpioCntlrFromHdfDev(device);
if (gpioCntlr == NULL) {
HDF_LOGE("GpioCntlrFromHdfDev fail\r\n");
return HDF_DEV_ERR_NO_DEVICE_SERVICE;
}
ret = AttachGpioDevice(gpioCntlr, device); /* GpioCntlr add GpioDevice to priv */
if (ret != HDF_SUCCESS) {
HDF_LOGE("AttachGpioDevice fail\r\n");
return HDF_DEV_ERR_ATTACHDEV_FAIL;
}
gpioCntlr->ops = &g_GpioCntlrMethod; /* register callback */
ret = GpioCntlrAdd(gpioCntlr);
if (ret != HDF_SUCCESS) {
HDF_LOGE("GpioCntlrAdd fail %d\r\n", gpioCntlr->start);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t GpioDriverBind(struct HdfDeviceObject *device)
{
if (device == NULL) {
HDF_LOGE("device object is NULL\n");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static void GpioDriverRelease(struct HdfDeviceObject *device)
{
struct GpioCntlr *gpioCntlr = NULL;
if (device == NULL) {
HDF_LOGE("%s: device is NULL", __func__);
return;
}
gpioCntlr = GpioCntlrFromHdfDev(device);
if (gpioCntlr == NULL) {
HDF_LOGE("%s: host is NULL", __func__);
return;
}
gpioCntlr->count = 0;
}
/* dev api */
static int32_t GpioDevWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val)
{
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
HDF_LOGE("%s %d ,write pin num %d", __func__, __LINE__, realPin);
GPIO_TypeDef* gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];
if (val) {
LL_GPIO_SetOutputPin(gpiox, pinReg);
} else {
LL_GPIO_ResetOutputPin(gpiox, pinReg);
}
return HDF_SUCCESS;
}
static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val)
{
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
uint16_t value = 0;
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
GPIO_TypeDef* gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];
value = LL_GPIO_ReadInputPin(gpiox, pinReg);
*val = value;
return HDF_SUCCESS;
}
static int32_t GpioDevSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
{
(void)cntlr;
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
uint16_t value = 0;
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
GPIO_TypeDef* gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];
LL_GPIO_SetPinMode(gpiox, pinReg, dir);
return HDF_SUCCESS;
}
static int32_t GpioDevGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
{
(void)cntlr;
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
uint16_t value = 0;
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
GPIO_TypeDef* gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];
value = LL_GPIO_GetPinMode(gpiox, pinReg);
*dir = value;
return HDF_SUCCESS;
}
static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode)
{
(void)cntlr;
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
if (mode == OSAL_IRQF_TRIGGER_RISING) {
g_gpioExitCfg[gpio].trigger = LL_EXTI_TRIGGER_RISING;
} else if (mode == OSAL_IRQF_TRIGGER_FALLING) {
g_gpioExitCfg[gpio].trigger = LL_EXTI_TRIGGER_FALLING;
} else {
HDF_LOGE("%s %d, error mode:%d", __func__, __LINE__, mode);
return HDF_ERR_NOT_SUPPORT;
}
return HDF_SUCCESS;
}
static int32_t GpioDevUnSetIrq(struct GpioCntlr *cntlr, uint16_t gpio)
{
(void)cntlr;
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
return HDF_SUCCESS;
}
static int32_t GpioDevEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
{
(void)cntlr;
LL_EXTI_InitConfig exitInitConfig = {0};
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
exitInitConfig.Exithandler = OemGpioIrqHdl;
exitInitConfig.Gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];
exitInitConfig.initType.Line_0_31 = g_gpioExitLineMap[g_gpioPinsMap[gpio].realPin];
exitInitConfig.initType.LineCommand = ENABLE;
exitInitConfig.initType.Mode = LL_EXTI_MODE_IT;
exitInitConfig.PinReg = pinReg;
exitInitConfig.initType.Trigger = g_gpioExitCfg[gpio].trigger;
LL_SETUP_EXTI(&exitInitConfig, g_gpioPinsMap[gpio].realPin, gpio, g_gpioPinsMap[gpio].group);
return HDF_SUCCESS;
}
static int32_t GpioDevDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
{
(void)cntlr;
LL_EXTI_InitConfig exitInitConfig = {0};
uint16_t realPin = g_gpioPinsMap[gpio].realPin;
uint32_t pinReg = g_stmRealPinMaps[realPin];
if (pinReg > LL_GPIO_PIN_15 || pinReg < LL_GPIO_PIN_0) {
HDF_LOGE("%s %d, error pin:%d", __func__, __LINE__, realPin);
return HDF_ERR_NOT_SUPPORT;
}
exitInitConfig.Exithandler = NULL;
exitInitConfig.Gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];
exitInitConfig.initType.Line_0_31 = g_gpioExitLineMap[g_gpioPinsMap[gpio].realPin];
exitInitConfig.initType.LineCommand = DISABLE;
exitInitConfig.initType.Mode = LL_EXTI_MODE_IT;
exitInitConfig.PinReg = pinReg;
exitInitConfig.initType.Trigger = g_gpioExitCfg[gpio].trigger;
LL_SETUP_EXTI(&exitInitConfig, g_gpioPinsMap[gpio].realPin, gpio, g_gpioPinsMap[gpio].group);
return HDF_SUCCESS;
}
+7
View File
@@ -19,10 +19,17 @@ hdf_driver(module_name) {
if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) {
sources += [ "i2c_wm.c" ]
}
if (defined(LOSCFG_SOC_SERIES_STM32F4xx)) {
sources += [ "i2c_stm32f4xx.c" ]
}
include_dirs = [ "." ]
if (defined(LOSCFG_SHIELD_V200ZR_EVB_T1) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/fnlink/shields" ]
}
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
+395
View File
@@ -0,0 +1,395 @@
/*
* Copyright (c) 2022 Talkweb Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include <stdlib.h>
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#include "hcs_macro.h"
#include "hdf_config_macro.h"
#else
#include "device_resource_if.h"
#endif
#include "hdf_device_desc.h"
#include "hdf_log.h"
#include "i2c_core.h"
#include "i2c_if.h"
#include "osal_mutex.h"
#include "hdf_base_hal.h"
#include "stm32f4xx_ll_i2c.h"
#define HDF_LOG_TAG "hdf_i2c"
typedef enum {
I2C_HANDLE_NULL = 0,
I2C_HANDLE_1 = 1,
I2C_HANDLE_2 = 2,
I2C_HANDLE_3 = 3,
I2C_HANDLE_MAX = I2C_HANDLE_3
} I2C_HANDLE;
struct RealI2cResource {
uint8_t port;
uint8_t devMode;
uint32_t devAddr;
uint32_t speed;
struct OsalMutex mutex;
};
static bool g_I2cEnableFlg[I2C_HANDLE_MAX] = {0};
static void HdfI2cInit(I2C_HANDLE i2cx, unsigned int i2cRate, unsigned int addr);
static void HdfI2cWrite(I2C_HANDLE i2cx, unsigned char devAddr, unsigned char *buf, unsigned int len);
static void HdfI2cRead(I2C_HANDLE i2cx, unsigned char devAddr, unsigned char *buf, unsigned int len);
static int32_t I2cDriverBind(struct HdfDeviceObject *device);
static int32_t I2cDriverInit(struct HdfDeviceObject *device);
static void I2cDriverRelease(struct HdfDeviceObject *device);
static int32_t I2cDataTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count);
struct HdfDriverEntry gI2cHdfDriverEntry = {
.moduleVersion = 1,
.moduleName = "HDF_I2C",
.Bind = I2cDriverBind,
.Init = I2cDriverInit,
.Release = I2cDriverRelease,
};
HDF_INIT(gI2cHdfDriverEntry);
struct I2cMethod gI2cHostMethod = {
.transfer = I2cDataTransfer,
};
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#define I2C_FIND_CONFIG(node, name, resource) \
do { \
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
resource->port = HCS_PROP(node, port); \
resource->devMode = HCS_PROP(node, devMode); \
resource->devAddr = HCS_PROP(node, devAddr); \
resource->speed = HCS_PROP(node, speed); \
result = HDF_SUCCESS; \
} \
} while (0)
#define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
#define PLATFORM_I2C_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), i2c_config)
static uint32_t GetI2cDeviceResource(struct RealI2cResource *i2cResource, const char *deviceMatchAttr)
{
int32_t result = HDF_FAILURE;
struct RealI2cResource *resource = NULL;
if (i2cResource == NULL || deviceMatchAttr == NULL) {
HDF_LOGE("device or deviceMatchAttr is NULL\r\n");
return HDF_ERR_INVALID_PARAM;
}
resource = i2cResource;
#if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, i2c_config)
HCS_FOREACH_CHILD_VARGS(PLATFORM_I2C_CONFIG, I2C_FIND_CONFIG, deviceMatchAttr, resource);
#endif
if (result != HDF_SUCCESS) {
HDF_LOGE("resourceNode %s is NULL\r\n", deviceMatchAttr);
} else {
HdfI2cInit(i2cResource->port, i2cResource->speed, i2cResource->devAddr);
}
return result;
}
#else
static int32_t GetI2cDeviceResource(struct RealI2cResource *i2cResource, const struct DeviceResourceNode *resourceNode)
{
if (i2cResource == NULL || resourceNode == NULL) {
HDF_LOGE("[%s]: param is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
struct DeviceResourceIface *dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
if (dri == NULL || dri->GetUint8 == NULL || dri->GetUint32 == NULL || dri->GetUint32Array == NULL) {
HDF_LOGE("DeviceResourceIface is invalid\r\n");
return HDF_ERR_INVALID_OBJECT;
}
if (dri->GetUint8(resourceNode, "port", &i2cResource->port, 0) != HDF_SUCCESS) {
HDF_LOGE("i2c config port fail\r\n");
return HDF_FAILURE;
}
if (dri->GetUint8(resourceNode, "devMode", &i2cResource->devMode, 0) != HDF_SUCCESS) {
HDF_LOGE("i2c config devMode fail\r\n");
return HDF_FAILURE;
}
if (dri->GetUint32(resourceNode, "devAddr", &i2cResource->devAddr, 0) != HDF_SUCCESS) {
HDF_LOGE("i2c config devAddr fail\r\n");
return HDF_FAILURE;
}
if (dri->GetUint32(resourceNode, "speed", &i2cResource->speed, 0) != HDF_SUCCESS) {
HDF_LOGE("i2c config speed fail\r\n");
return HDF_FAILURE;
}
HdfI2cInit(i2cResource->port, i2cResource->speed, i2cResource->devAddr);
return HDF_SUCCESS;
}
#endif
static int32_t AttachI2cDevice(struct I2cCntlr *host, struct HdfDeviceObject *device)
{
int32_t ret = HDF_FAILURE;
if (host == NULL || device == NULL) {
HDF_LOGE("[%s]: param is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
struct RealI2cResource *i2cResource = (struct RealI2cResource *)OsalMemAlloc(sizeof(struct RealI2cResource));
if (i2cResource == NULL) {
HDF_LOGE("[%s]: OsalMemAlloc RealI2cResource fail\r\n", __func__);
return HDF_ERR_MALLOC_FAIL;
}
memset_s(i2cResource, sizeof(struct RealI2cResource), 0, sizeof(struct RealI2cResource));
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
ret = GetI2cDeviceResource(i2cResource, device->deviceMatchAttr);
#else
ret = GetI2cDeviceResource(i2cResource, device->property);
#endif
if (ret != HDF_SUCCESS) {
OsalMemFree(i2cResource);
return HDF_FAILURE;
}
host->busId = i2cResource->port;
host->priv = i2cResource;
return HDF_SUCCESS;
}
static int32_t I2cDataTransfer(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count)
{
if (cntlr == NULL || msgs == NULL || cntlr->priv == NULL) {
HDF_LOGE("[%s]: I2cDataTransfer param is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (count <= 0) {
HDF_LOGE("[%s]: I2cDataTransfer count err\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
struct RealI2cResource *device = (struct I2cDevice *)cntlr->priv;
if (device == NULL) {
HDF_LOGE("%s: I2cDevice is NULL\r\n", __func__);
return HDF_DEV_ERR_NO_DEVICE;
}
struct I2cMsg *msg = NULL;
if (HDF_SUCCESS != OsalMutexLock(&device->mutex)) {
HDF_LOGE("[%s]: OsalMutexLock fail\r\n", __func__);
return HDF_ERR_TIMEOUT;
}
for (int32_t i = 0; i < count; i++) {
msg = &msgs[i];
if (msg->flags == I2C_FLAG_READ) {
HdfI2cRead(device->port, msg->addr, msg->buf, msg->len);
} else {
HdfI2cWrite(device->port, msg->addr, msg->buf, msg->len);
}
}
OsalMutexUnlock(&device->mutex);
return count;
}
static int32_t I2cDriverBind(struct HdfDeviceObject *device)
{
if (device == NULL) {
HDF_LOGE("[%s]: I2c device is NULL\r\n", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t I2cDriverInit(struct HdfDeviceObject *device)
{
int32_t ret = HDF_FAILURE;
struct I2cCntlr *host = NULL;
if (device == NULL) {
HDF_LOGE("[%s]: I2c device is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
host = (struct I2cCntlr *)OsalMemAlloc(sizeof(struct I2cCntlr));
if (host == NULL) {
HDF_LOGE("[%s]: malloc host is NULL\r\n", __func__);
return HDF_ERR_MALLOC_FAIL;
}
memset_s(host, sizeof(struct I2cCntlr), 0, sizeof(struct I2cCntlr));
host->ops = &gI2cHostMethod;
device->priv = (void *)host;
ret = AttachI2cDevice(host, device);
if (ret != HDF_SUCCESS) {
HDF_LOGE("[%s]: AttachI2cDevice error, ret = %d\r\n", __func__, ret);
I2cDriverRelease(device);
return HDF_DEV_ERR_ATTACHDEV_FAIL;
}
ret = I2cCntlrAdd(host);
if (ret != HDF_SUCCESS) {
I2cDriverRelease(device);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static void I2cDriverRelease(struct HdfDeviceObject *device)
{
if (device == NULL) {
HDF_LOGE("%s: device is NULL\r\n", __func__);
return;
}
struct I2cCntlr *i2cCntrl = device->priv;
if (i2cCntrl == NULL || i2cCntrl->priv == NULL) {
HDF_LOGE("%s: i2cCntrl is NULL\r\n", __func__);
return;
}
i2cCntrl->ops = NULL;
struct RealI2cResource *i2cDevice = (struct I2cDevice *)i2cCntrl->priv;
OsalMemFree(i2cCntrl);
if (i2cDevice != NULL) {
OsalMutexDestroy(&i2cDevice->mutex);
OsalMemFree(i2cDevice);
}
}
static I2C_TypeDef *GetLLI2cHandlerMatch(I2C_HANDLE i2cx)
{
if (i2cx > I2C_HANDLE_MAX) {
printf("ERR: GetLLI2cClkMatch fail, param match fail\r\n");
return NULL;
}
switch (i2cx) {
case I2C_HANDLE_1:
return (I2C_TypeDef *)I2C1;
case I2C_HANDLE_2:
return (I2C_TypeDef *)I2C2;
case I2C_HANDLE_3:
return (I2C_TypeDef *)I2C3;
default:
printf("ERR: GetLLI2cClkMatch fail, handler match fail\r\n");
return NULL;
}
}
static bool EnableLLI2cClock(I2C_TypeDef *i2cx)
{
if (i2cx == I2C1) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
return true;
} else if (i2cx == I2C2) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2);
return true;
} else if (i2cx == I2C3) {
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
return true;
} else {
printf("EnableI2cClock fail, i2cx match fail\r\n");
return false;
}
}
static void HdfI2cInit(I2C_HANDLE i2cx, unsigned int i2cRate, unsigned int addr)
{
LL_I2C_InitTypeDef I2C_InitStruct = {0};
I2C_TypeDef *myI2c = GetLLI2cHandlerMatch(i2cx);
if (myI2c == NULL) {
return;
}
EnableLLI2cClock(myI2c);
LL_I2C_DisableOwnAddress2(myI2c);
LL_I2C_DisableGeneralCall(myI2c);
LL_I2C_EnableClockStretching(myI2c);
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.ClockSpeed = i2cRate;
I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2;
I2C_InitStruct.OwnAddress1 = addr;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
LL_I2C_Init(myI2c, &I2C_InitStruct);
LL_I2C_SetOwnAddress2(myI2c, 0);
g_I2cEnableFlg[i2cx] = true;
}
static void HdfI2cWrite(I2C_HANDLE i2cx, unsigned char devAddr, unsigned char *buf, unsigned int len)
{
if (g_I2cEnableFlg[i2cx] != true) {
printf("I2C_WriteByte err, Please initialize first!");
return;
}
I2C_TypeDef *myI2c = GetLLI2cHandlerMatch(i2cx);
if (myI2c == NULL) {
return;
}
while (LL_I2C_IsActiveFlag_BUSY(myI2c));
LL_I2C_GenerateStartCondition(myI2c);
while (LL_I2C_IsActiveFlag_SB(myI2c) == RESET);
LL_I2C_TransmitData8(myI2c, (devAddr << 1));
while (LL_I2C_IsActiveFlag_TXE(myI2c) == RESET);
LL_I2C_ClearFlag_ADDR(myI2c);
while (LL_I2C_IsActiveFlag_TXE(myI2c) == RESET);
for (unsigned int i = 0; i < len; i++) {
LL_I2C_TransmitData8(myI2c, buf[i]);
while (LL_I2C_IsActiveFlag_TXE(myI2c) == RESET);
}
LL_I2C_GenerateStopCondition(myI2c);
}
static void HdfI2cRead(I2C_HANDLE i2cx, unsigned char devAddr, unsigned char *buf, unsigned int len)
{
if (g_I2cEnableFlg[i2cx] != true) {
printf("I2C_ReadByte err, Please initialize first!");
return;
}
I2C_TypeDef *myI2c = GetLLI2cHandlerMatch(i2cx);
if (myI2c == NULL) {
return;
}
while (LL_I2C_IsActiveFlag_BUSY(myI2c));
LL_I2C_GenerateStartCondition(myI2c);
while (LL_I2C_IsActiveFlag_SB(myI2c) == RESET);
LL_I2C_TransmitData8(myI2c, ((devAddr << 1) | 1));
while ((LL_I2C_IsActiveFlag_ADDR(myI2c) == RESET) || (LL_I2C_IsActiveFlag_MSL(myI2c) == RESET) ||
(LL_I2C_IsActiveFlag_BUSY(myI2c) == RESET));
for (unsigned int i = 0; i < len; i++) {
if (i < len - 1) {
LL_I2C_AcknowledgeNextData(myI2c, LL_I2C_ACK);
} else {
LL_I2C_AcknowledgeNextData(myI2c, LL_I2C_NACK);
}
while (LL_I2C_IsActiveFlag_RXNE(myI2c) == RESET);
buf[i] = LL_I2C_ReceiveData8(myI2c);
}
LL_I2C_GenerateStopCondition(myI2c);
}
+7
View File
@@ -19,10 +19,17 @@ hdf_driver(module_name) {
if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) {
sources += [ "pwm_wm.c" ]
}
if (defined(LOSCFG_SOC_SERIES_STM32F4xx)) {
sources += [ "pwm_stm32f4xx.c" ]
}
include_dirs = [ "." ]
if (defined(LOSCFG_SHIELD_V200ZR_EVB_T1) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/fnlink/shields" ]
}
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
+591
View File
@@ -0,0 +1,591 @@
/*
* Copyright (c) 2022 Talkweb Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#include "hcs_macro.h"
#include "hdf_config_macro.h"
#else
#include "device_resource_if.h"
#endif
#include "hdf_device_desc.h"
#include "pwm_core.h"
#include "hdf_log.h"
#include "hdf_base_hal.h"
#include "stm32f4xx_ll_tim.h"
#define GPIO_STR_MAX_LENGTH 32
typedef enum {
PWM_CH1 = 0,
PWM_CH2,
PWM_CH3,
PWM_CH4,
PWM_CH_MAX
} PWM_CH;
typedef enum {
PWM_TIM1 = 0,
PWM_TIM2,
PWM_TIM3,
PWM_TIM4,
PWM_TIM5,
PWM_TIM6,
PWM_TIM7,
PWM_TIM8,
PWM_TIM9,
PWM_TIM10,
PWM_TIM11,
PWM_TIM12,
PWM_TIM13,
PWM_TIM14,
PWM_TIM_MAX
} PWM_TIM;
typedef struct {
PWM_CH pwmCh;
PWM_TIM pwmTim;
uint32_t prescaler;
uint32_t timPeroid;
uint32_t realHz;
} PwmResource;
typedef struct {
LL_TIM_InitTypeDef timInitStruct;
LL_TIM_OC_InitTypeDef timOcInitStruct;
} PwmConfig;
typedef struct {
struct IDeviceIoService ioService;
PwmConfig stPwmCfg;
struct PwmConfig *cfg;
PwmResource resource;
} PwmDevice;
typedef struct {
uint32_t period;
uint32_t duty;
PWM_TIM pwmCh;
PWM_TIM pwmTim;
} PwmFreqArg;
static TIM_TypeDef* g_stTimMap[PWM_TIM_MAX] = {
TIM1,
TIM2,
TIM3,
TIM4,
TIM5,
TIM6,
TIM7,
TIM8,
TIM9,
TIM10,
TIM11,
TIM12,
TIM13,
TIM14,
};
static uint32_t g_stChannelMap[PWM_CH_MAX] = {
LL_TIM_CHANNEL_CH1,
LL_TIM_CHANNEL_CH2,
LL_TIM_CHANNEL_CH3,
LL_TIM_CHANNEL_CH4,
};
static uint32_t g_stTimIrqMap[PWM_TIM_MAX] = {
TIM1_CC_IRQn,
TIM2_IRQn,
TIM3_IRQn,
TIM4_IRQn,
TIM5_IRQn,
TIM6_DAC_IRQn,
TIM7_IRQn,
TIM8_CC_IRQn,
TIM1_BRK_TIM9_IRQn,
TIM1_UP_TIM10_IRQn,
TIM1_TRG_COM_TIM11_IRQn,
TIM8_BRK_TIM12_IRQn,
TIM8_UP_TIM13_IRQn,
TIM8_TRG_COM_TIM14_IRQn,
};
static uint32_t g_stTimFreq[PWM_TIM_MAX] = { // tim2-tim7, tim12-tim14 is 84MTIM1、TIM8~TIM11 is 168M
168000000,
84000000,
84000000,
84000000,
84000000,
84000000,
84000000,
168000000,
168000000,
168000000,
168000000,
84000000,
84000000,
};
#define PER_SEC_NSEC 1000000000
static int32_t PwmDevSetConfig(struct PwmDev *pwm, struct PwmConfig *config);
static int32_t PwmDevOpen(struct PwmDev *pwm);
static int32_t PwmDevClose(struct PwmDev *pwm);
struct PwmMethod g_pwmmethod = {
.setConfig = PwmDevSetConfig,
.open = PwmDevOpen,
.close = PwmDevClose,
};
static void InitPwmClock(PWM_TIM tim)
{
switch (tim) {
case PWM_TIM1:
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
break;
case PWM_TIM2:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
break;
case PWM_TIM3:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
break;
case PWM_TIM4:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
break;
case PWM_TIM5:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM5);
break;
case PWM_TIM6:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM6);
break;
case PWM_TIM7:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM7);
break;
case PWM_TIM8:
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM8);
break;
case PWM_TIM9:
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM9);
break;
case PWM_TIM10:
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM10);
break;
case PWM_TIM11:
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM11);
break;
case PWM_TIM12:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM12);
break;
case PWM_TIM13:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM13);
break;
case PWM_TIM14:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM14);
break;
default:
break;
}
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#define PWM_FIND_CONFIG(node, name, resource) \
do { \
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
uint8_t tim = HCS_PROP(node, pwmTim); \
uint8_t ch = HCS_PROP(node, pwmCh); \
uint8_t prescaler = HCS_PROP(node, prescaler); \
resource->pwmCh = ch; \
resource->pwmTim = tim; \
resource->prescaler = prescaler; \
result = HDF_SUCCESS; \
} \
} while (0)
#define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
#define PLATFORM_PWM_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), pwm_config)
static uint32_t GetPwmDeviceResource(PwmDevice *device, const char *deviceMatchAttr)
{
int32_t result = HDF_FAILURE;
PwmResource *resource = NULL;
if (device == NULL || deviceMatchAttr == NULL) {
HDF_LOGE("%s: device or deviceMatchAttr is NULL", __func__);
return HDF_ERR_INVALID_PARAM;
}
resource = &device->resource;
#if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, pwm_config)
HCS_FOREACH_CHILD_VARGS(PLATFORM_PWM_CONFIG, PWM_FIND_CONFIG, deviceMatchAttr, resource);
#endif
if (result != HDF_SUCCESS) {
HDF_LOGE("resourceNode %s is NULL\r\n", deviceMatchAttr);
}
return result;
}
#else
static int32_t GetPwmDeviceResource(PwmDevice *device, const struct DeviceResourceNode *resourceNode)
{
struct DeviceResourceIface *dri = NULL;
PwmResource *resource = NULL;
if (device == NULL || resourceNode == NULL) {
HDF_LOGE("resource or device is NULL\r\n");
return HDF_ERR_INVALID_PARAM;
}
resource = &device->resource;
if (resource == NULL) {
HDF_LOGE("resource is NULL\r\n");
return HDF_ERR_INVALID_OBJECT;
}
dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
if (dri == NULL || dri->GetUint8 == NULL || dri->GetUint32 == NULL) {
HDF_LOGE("DeviceResourceIface is invalid\r\n");
return HDF_ERR_INVALID_PARAM;
}
if (dri->GetUint8(resourceNode, "pwmTim", &resource->pwmTim, 0) != HDF_SUCCESS) {
HDF_LOGE("read pwmPin fail\r\n");
return HDF_ERR_INVALID_PARAM;
}
if (resource->pwmTim == PWM_TIM6 || resource->pwmTim == PWM_TIM7) {
HDF_LOGE("unsupport tim\r\n");
return HDF_ERR_INVALID_PARAM;
}
if (dri->GetUint8(resourceNode, "pwmCh", &resource->pwmCh, 0) != HDF_SUCCESS) {
HDF_LOGE("read pwmCh fail\r\n");
return HDF_FAILURE;
}
if (dri->GetUint32(resourceNode, "prescaler", &resource->prescaler, 0) != HDF_SUCCESS) {
HDF_LOGE("read prescaler fail\r\n");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
#endif
static int32_t AttachPwmDevice(struct PwmDev *host, struct HdfDeviceObject *device)
{
int32_t ret;
PwmDevice *pwmDevice = NULL;
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
if (device == NULL || host == NULL) {
#else
if (device == NULL || device->property == NULL || host == NULL) {
#endif
HDF_LOGE("%s: param is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
pwmDevice = (PwmDevice *)OsalMemAlloc(sizeof(PwmDevice));
if (pwmDevice == NULL) {
HDF_LOGE("%s: OsalMemAlloc pwmDevice error\r\n", __func__);
return HDF_ERR_MALLOC_FAIL;
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
ret = GetPwmDeviceResource(pwmDevice, device->deviceMatchAttr);
#else
ret = GetPwmDeviceResource(pwmDevice, device->property);
#endif
if (ret != HDF_SUCCESS) {
(void)OsalMemFree(pwmDevice);
return HDF_FAILURE;
}
host->priv = pwmDevice;
host->num = pwmDevice->resource.pwmTim;
return HDF_SUCCESS;
}
static int32_t PwmDriverBind(struct HdfDeviceObject *device);
static int32_t PwmDriverInit(struct HdfDeviceObject *device);
static void PwmDriverRelease(struct HdfDeviceObject *device);
struct HdfDriverEntry g_pwmDriverEntry = {
.moduleVersion = 1,
.moduleName = "ST_HDF_PLATFORM_PWM",
.Bind = PwmDriverBind,
.Init = PwmDriverInit,
.Release = PwmDriverRelease,
};
HDF_INIT(g_pwmDriverEntry);
static int32_t PwmDriverBind(struct HdfDeviceObject *device)
{
struct PwmDev *devService = NULL;
if (device == NULL) {
HDF_LOGE("hdfDevice object is null!\r\n");
return HDF_FAILURE;
}
devService = (struct PwmDev *)OsalMemCalloc(sizeof(struct PwmDev));
if (devService == NULL) {
HDF_LOGE("malloc pwmDev failed\n");
}
device->service = &devService->service;
devService->device = device;
return HDF_SUCCESS;
}
static int32_t PwmDriverInit(struct HdfDeviceObject *device)
{
int32_t ret;
struct PwmDev *host = NULL;
if (device == NULL) {
HDF_LOGE("%s: device is NULL\r\n", __func__);
return HDF_ERR_INVALID_OBJECT;
}
host = (struct PwmDev *)device->service;
if (host == NULL) {
HDF_LOGE("%s: host is NULL\r\n", __func__);
return HDF_ERR_MALLOC_FAIL;
}
ret = AttachPwmDevice(host, device);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:attach error\r\n", __func__);
return HDF_DEV_ERR_ATTACHDEV_FAIL;
}
host->method = &g_pwmmethod;
ret = PwmDeviceAdd(device, host);
if (ret != HDF_SUCCESS) {
PwmDeviceRemove(device, host);
OsalMemFree(host->device);
OsalMemFree(host);
return HDF_DEV_ERR_NO_DEVICE;
}
return HDF_SUCCESS;
}
static void PwmDriverRelease(struct HdfDeviceObject *device)
{
struct PwmDev *host = NULL;
if (device == NULL || device->service == NULL) {
HDF_LOGE("device is null\r\n");
return;
}
host = (struct PwmDev *)device->service;
if (host != NULL && host->device != NULL) {
host->method = NULL;
OsalMemFree(host->device);
OsalMemFree(host);
host->device = NULL;
host = NULL;
}
device->service = NULL;
host = NULL;
return;
}
static int32_t InitPwmFreqAndPeriod(const struct PwmConfig *config, PwmFreqArg* arg, const PwmResource *resource)
{
if (arg == NULL) {
HDF_LOGE("null ptr\r\n");
return HDF_FAILURE;
}
uint32_t freq = 0;
uint32_t period = 0;
uint32_t duty = 0;
uint32_t realHz = 0;
if (config->period != 0) {
freq = (uint32_t)(PER_SEC_NSEC / config->period);
} else {
HDF_LOGE("invalid div\r\n");
return HDF_FAILURE;
}
realHz = (uint32_t)(((double)g_stTimFreq[arg->pwmTim]) / ((double)(resource->prescaler + 1)));
if (freq != 0) {
period = (uint32_t)(realHz / freq);
} else {
HDF_LOGE("invalid div\r\n");
return HDF_FAILURE;
}
if (config->period != 0) {
duty = (uint32_t)(((double)config->duty / (double)config->period) * period);
} else {
HDF_LOGE("invalid div\r\n");
return HDF_FAILURE;
}
arg->period = period;
arg->duty = duty;
return HDF_SUCCESS;
}
static void InitTimPwm(const PwmFreqArg* arg, const struct PwmConfig *config,
PwmConfig *pwmCfg, const PwmResource *resource)
{
if (arg == NULL) {
HDF_LOGE("null ptr\r\n");
return;
}
pwmCfg->timInitStruct.Autoreload = arg->period - 1; // if period is 1000 20KHz/1000=20Hzperiod is 50ms
pwmCfg->timInitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
pwmCfg->timInitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
pwmCfg->timInitStruct.Prescaler = resource->prescaler;
LL_TIM_Init(g_stTimMap[arg->pwmTim], &pwmCfg->timInitStruct);
LL_TIM_EnableARRPreload(g_stTimMap[arg->pwmTim]);
LL_TIM_SetClockSource(g_stTimMap[arg->pwmTim], LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_SetTriggerOutput(g_stTimMap[arg->pwmTim], LL_TIM_TRGO_RESET);
LL_TIM_DisableMasterSlaveMode(g_stTimMap[arg->pwmTim]);
pwmCfg->timOcInitStruct.OCMode = LL_TIM_OCMODE_PWM1; // PWM1 mode
pwmCfg->timOcInitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
pwmCfg->timOcInitStruct.CompareValue = arg->duty;
if (config->polarity == PWM_NORMAL_POLARITY) {
pwmCfg->timOcInitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
} else {
pwmCfg->timOcInitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW;
}
pwmCfg->timOcInitStruct.OCIdleState = LL_TIM_OCPOLARITY_LOW;
LL_TIM_OC_Init(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh], &pwmCfg->timOcInitStruct);
LL_TIM_OC_DisableFast(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh]);
if (arg->pwmTim == PWM_TIM1 || arg->pwmTim == PWM_TIM8) {
LL_TIM_BDTR_InitTypeDef bdtrInitStruct = {0};
bdtrInitStruct.OSSRState = LL_TIM_OSSR_DISABLE;
bdtrInitStruct.OSSIState = LL_TIM_OSSI_DISABLE;
bdtrInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF;
bdtrInitStruct.DeadTime = 0; // dead area time 200ns 0x28
bdtrInitStruct.BreakState = LL_TIM_BREAK_ENABLE;
bdtrInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
bdtrInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_ENABLE;
LL_TIM_BDTR_Init(g_stTimMap[arg->pwmTim], &bdtrInitStruct);
}
NVIC_SetPriority(g_stTimIrqMap[arg->pwmTim], NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 1, 1));
NVIC_EnableIRQ(g_stTimIrqMap[arg->pwmTim]);
if (arg->pwmTim == PWM_TIM1 || arg->pwmTim == PWM_TIM8) {
LL_TIM_EnableAutomaticOutput(g_stTimMap[arg->pwmTim]);
LL_TIM_GenerateEvent_UPDATE(g_stTimMap[arg->pwmTim]);
}
LL_TIM_EnableCounter(g_stTimMap[arg->pwmTim]);
LL_TIM_CC_EnableChannel(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh]);
LL_TIM_OC_EnablePreload(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh]);
return;
}
static void DeInitTimPwm(PWM_TIM pwmId, PWM_CH pwmCh)
{
LL_TIM_DeInit(g_stTimMap[pwmId]);
LL_TIM_OC_DisableClear(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
NVIC_DisableIRQ(g_stTimIrqMap[pwmId]);
LL_TIM_DisableCounter(g_stTimMap[pwmId]);
LL_TIM_CC_DisableChannel(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
LL_TIM_OC_DisablePreload(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
if (pwmId== PWM_TIM1 || pwmId == PWM_TIM8) {
LL_TIM_DisableAutomaticOutput(g_stTimMap[pwmId]);
}
return;
}
static int32_t PwmDevSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
{
PwmDevice *prvPwm = NULL;
PwmConfig *pwmCfg = NULL;
PWM_TIM pwmId;
PWM_CH pwmCh;
PwmResource *resource = NULL;
if (pwm == NULL || config == NULL || (config->period > PER_SEC_NSEC)) {
HDF_LOGE("%s\r\n", __FUNCTION__);
return HDF_FAILURE;
}
prvPwm = (struct PwmDevice *)PwmGetPriv(pwm);
if (prvPwm == NULL) {
return HDF_FAILURE;
}
resource = &prvPwm->resource;
if (resource == NULL) {
return HDF_FAILURE;
}
pwmCfg = &prvPwm->stPwmCfg;
if (pwmCfg == NULL) {
return HDF_FAILURE;
}
pwmId = prvPwm->resource.pwmTim;
pwmCh = prvPwm->resource.pwmCh;
if (config->status == PWM_ENABLE_STATUS) {
PwmFreqArg arg = {0};
arg.pwmCh = pwmCh;
arg.pwmTim = pwmId;
if (InitPwmFreqAndPeriod(config, &arg, resource) != HDF_SUCCESS) {
HDF_LOGE("calculate freq and period failed!\r\n");
return HDF_FAILURE;
}
InitPwmClock(pwmId);
InitTimPwm(&arg, config, pwmCfg, resource);
} else {
DeInitTimPwm(pwmId, pwmCh);
}
return HDF_SUCCESS;
}
static int32_t PwmDevOpen(struct PwmDev *pwm)
{
if (pwm == NULL) {
HDF_LOGE("%s\r\n", __FUNCTION__);
return HDF_ERR_INVALID_PARAM;
}
return HDF_SUCCESS;
}
static int32_t PwmDevClose(struct PwmDev *pwm)
{
PwmDevice *prvPwm = NULL;
PWM_TIM pwmId;
PWM_CH pwmCh;
if (pwm == NULL) {
HDF_LOGE("%s\r\n", __FUNCTION__);
return HDF_ERR_INVALID_PARAM;
}
prvPwm = (PwmDevice *)PwmGetPriv(pwm);
if (prvPwm == NULL) {
HDF_LOGE("%s\r\n", __FUNCTION__);
return HDF_DEV_ERR_NO_DEVICE;
}
pwmId = prvPwm->resource.pwmTim;
pwmCh = prvPwm->resource.pwmCh;
LL_TIM_DeInit(g_stTimMap[pwmId]);
LL_TIM_OC_DisableClear(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
NVIC_DisableIRQ(g_stTimIrqMap[pwmId]);
return HDF_SUCCESS;
}
+7
View File
@@ -19,10 +19,17 @@ hdf_driver(module_name) {
if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) {
sources += [ "spi_wm.c" ]
}
if (defined(LOSCFG_SOC_SERIES_STM32F4xx)) {
sources += [ "spi_stm32f4xx.c" ]
}
include_dirs = [ "." ]
if (defined(LOSCFG_SHIELD_V200ZR_EVB_T1) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/fnlink/shields" ]
}
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
+765
View File
@@ -0,0 +1,765 @@
/*
* Copyright (c) 2022 Talkweb Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include <stdlib.h>
#include <string.h>
#include "hal_gpio.h"
#include "hal_spi.h"
#include "osal_mutex.h"
#include "osal_sem.h"
#include "spi_core.h"
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#include "hcs_macro.h"
#include "hdf_config_macro.h"
#else
#include "device_resource_if.h"
#include "hdf_log.h"
#endif
#include "hdf_base_hal.h"
#define BITWORD_EIGHT 8
#define BITWORD_SIXTEEN 16
#define GPIO_STR_MAX 32
#define PER_MS_IN_SEC 1000
typedef enum {
SPI_WORK_MODE_0, // CPOL = 0; CPHA = 0
SPI_WORK_MODE_2, // CPOL = 1; CPHA = 0
SPI_WORK_MODE_1, // CPOL = 0; CPHA = 1
SPI_WORK_MODE_3, // CPOL = 1; CPHA = 1
SPI_WORD_MODE_MAX,
} SPI_CLK_MODE;
typedef enum {
SPI_TRANSFER_DMA,
SPI_TRANSFER_NORMAL,
SPI_TRANSFER_MAX,
} SPI_TRANS_MODE;
typedef enum {
FULL_DUPLEX = 0,
SIMPLE_RX,
HALF_RX,
HALF_TX,
SPI_TRANS_DIR_MAX,
} SPI_TRANS_DIR;
typedef enum {
SPI_SLAVE_MODE = 0,
SPI_MASTER_MODE,
SPI_MASTER_SLAVE_MAX,
} SPI_SLAVE_MASTER;
typedef enum {
SPI_DATA_WIDTH_8 = 0,
SPI_DATA_WIDTH_16,
SPI_DATA_WIDTH_MAX,
} SPI_DATA_WIDTH;
typedef enum {
SPI_NSS_SOFT_MODE = 0,
SPI_NSS_HARD_INPUT_MODE,
SPI_NSS_HARD_OUTPUT_MODE,
SPI_NSS_MODE_MAX,
} SPI_NSS;
typedef enum {
BAUD_RATE_DIV2 = 0,
BAUD_RATE_DIV4,
BAUD_RATE_DIV8,
BAUD_RATE_DIV16,
BAUD_RATE_DIV32,
BAUD_RATE_DIV64,
BAUD_RATE_DIV128,
BAUD_RATE_DIV256,
BAUD_RATE_DIV_MAX,
} SPI_BAUD_RATE;
typedef enum {
SPI_MSB_FIRST = 0,
SPI_LSB_FIRST,
SPI_MLSB_MAX,
} SPI_BYTE_ORDER;
typedef enum {
CRC_DISABLE = 0,
CRC_ENABLE,
CRC_STATE_MAX,
} CRC_CALULATION;
typedef enum {
SPI_PORT1 = 1,
SPI_PORT2,
SPI_PORT3,
} SPI_GROUPS;
typedef enum {
SPI_PROTO_MOTOROLA = 0,
SPI_PROTO_TI,
SPI_PROTO_MAX,
} SPI_PROTO_STANDARD;
typedef struct {
uint8_t busNum;
uint8_t csNum;
SPI_TRANS_DIR transDir;
SPI_TRANS_MODE transMode;
SPI_SLAVE_MASTER smMode;
SPI_CLK_MODE clkMode;
SPI_DATA_WIDTH dataWidth;
SPI_NSS nss;
SPI_BAUD_RATE baudRate;
SPI_BYTE_ORDER bitOrder;
CRC_CALULATION crcEnable;
SPI_GROUPS spix;
STM32_GPIO_PIN csPin;
STM32_GPIO_GROUP csGroup;
SPI_PROTO_STANDARD standard;
uint8_t dummyByte;
uint16_t crcPoly;
} SpiResource;
#define HCS_UINT8_PARSE_NUM 16
static const char *g_parseHcsMap[HCS_UINT8_PARSE_NUM] = {
"busNum",
"csNum",
"transDir",
"transMode",
"smMode",
"clkMode",
"dataWidth",
"nss",
"baudRate",
"bitOrder",
"crcEnable",
"spix",
"csPin",
"csGpiox",
"standard",
"dummyByte",
};
typedef struct {
struct OsalSem* sem;
struct OsalMutex* mutex;
SPI_TypeDef* spix;
} SPI_CONTEXT_T;
typedef struct {
uint32_t spiId;
SpiResource resource;
} SpiDevice;
static uint32_t g_transDirMaps[SPI_TRANS_DIR_MAX] = {
LL_SPI_FULL_DUPLEX,
LL_SPI_SIMPLEX_RX,
LL_SPI_HALF_DUPLEX_RX,
LL_SPI_HALF_DUPLEX_TX,
};
static uint32_t g_nssMaps[SPI_NSS_MODE_MAX] = {
LL_SPI_NSS_SOFT,
LL_SPI_NSS_HARD_INPUT,
LL_SPI_NSS_HARD_OUTPUT,
};
static uint32_t g_baudMaps[BAUD_RATE_DIV_MAX] = {
LL_SPI_BAUDRATEPRESCALER_DIV2,
LL_SPI_BAUDRATEPRESCALER_DIV4,
LL_SPI_BAUDRATEPRESCALER_DIV8,
LL_SPI_BAUDRATEPRESCALER_DIV16,
LL_SPI_BAUDRATEPRESCALER_DIV32,
LL_SPI_BAUDRATEPRESCALER_DIV64,
LL_SPI_BAUDRATEPRESCALER_DIV128,
LL_SPI_BAUDRATEPRESCALER_DIV256,
};
static SPI_TypeDef* g_spiGroupMaps[SPI_PORT3] = {
SPI1,
SPI2,
SPI3,
};
static void EnableSpiClock(uint32_t spiNum)
{
switch (spiNum) {
case SPI_PORT1:
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
break;
case SPI_PORT2:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
break;
case SPI_PORT3:
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3);
break;
default:
break;
}
}
static SPI_CONTEXT_T spiContext[SPI_PORT3] = {
{
.sem = {NULL},
.mutex = {NULL},
.spix = {NULL},
},
{
.sem = {NULL},
.mutex = {NULL},
.spix = {NULL},
},
{
.sem = {NULL},
.mutex = {NULL},
.spix = {NULL},
},
};
int32_t HalSpiSend(SpiDevice *spiDevice, const uint8_t *data, uint16_t size)
{
uint32_t spiId;
SpiResource *resource = NULL;
if (spiDevice == NULL || data == NULL || size == 0) {
HDF_LOGE("spi input para err\r\n");
return HDF_ERR_INVALID_PARAM;
}
spiId = spiDevice->spiId;
resource = &spiDevice->resource;
if (resource == NULL) {
HDF_LOGE("resource is null\r\n");
return HDF_ERR_INVALID_OBJECT;
}
if (resource->transMode == SPI_TRANSFER_DMA) {
return HDF_ERR_INVALID_PARAM; // unsupport now
} else {
uint8_t readData;
while (size--) {
readData = LL_SPI_Transmit(spiContext[spiId].spix, *data);
data++;
}
}
return HDF_SUCCESS;
}
int32_t HalSpiRecv(SpiDevice *spiDevice, uint8_t *data, uint16_t size)
{
uint32_t len = size;
uint32_t remainder = 0;
uint8_t *cmd = NULL;
uint32_t spiId;
SpiResource *resource = NULL;
if (spiDevice == NULL || data == NULL || size == 0) {
HDF_LOGE("spi input para err\r\n");
return HDF_ERR_INVALID_PARAM;
}
spiId = spiDevice->spiId;
resource = &spiDevice->resource;
if (resource == NULL) {
HDF_LOGE("resource is null\r\n");
return HDF_ERR_INVALID_OBJECT;
}
cmd = (uint8_t *)OsalMemAlloc(len);
if (cmd == NULL) {
HDF_LOGE("%s OsalMemAlloc size %ld error\r\n", __FUNCTION__, len);
return HDF_ERR_MALLOC_FAIL;
}
memset_s(cmd, len, resource->dummyByte, len);
if (resource->transMode == SPI_TRANSFER_DMA) {
return HDF_ERR_INVALID_PARAM; // unsupport now
} else {
while (len--) {
*data = LL_SPI_Transmit(spiContext[spiId].spix, *cmd);
data++;
cmd++;
}
}
OsalMemFree(cmd);
return HDF_SUCCESS;
}
int32_t HalSpiSendRecv(SpiDevice *spiDevice, uint8_t *txData,
uint16_t txSize, uint8_t *rxData, uint16_t rxSize)
{
uint32_t spiId;
uint8_t* data = rxData;
int16_t dropSize = 0;
SpiResource *resource = NULL;
if (spiDevice == NULL || txData == NULL || txSize == 0 || rxData == NULL || rxSize == 0) {
HDF_LOGE("spi input para err\r\n");
return HDF_ERR_INVALID_PARAM;
}
spiId = spiDevice->spiId;
resource = &spiDevice->resource;
if (resource->transMode == SPI_TRANSFER_DMA) {
return HDF_ERR_INVALID_PARAM; // unsupport now
} else {
while (rxSize--) {
*rxData = LL_SPI_Transmit(spiContext[spiId].spix, *txData);
rxData++;
txData++;
}
}
return HDF_SUCCESS;
}
static void InitSpiInitStruct(LL_SPI_InitTypeDef *spiInitStruct, const SpiResource *resource)
{
spiInitStruct->TransferDirection = g_transDirMaps[resource->transDir];
if (resource->smMode == SPI_SLAVE_MODE) {
spiInitStruct->Mode = LL_SPI_MODE_SLAVE;
} else {
spiInitStruct->Mode = LL_SPI_MODE_MASTER;
}
if (resource->dataWidth == SPI_DATA_WIDTH_8) {
spiInitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
} else {
spiInitStruct->DataWidth = LL_SPI_DATAWIDTH_16BIT;
}
switch (resource->clkMode) {
case SPI_WORK_MODE_0:
spiInitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
spiInitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
break;
case SPI_WORK_MODE_1:
spiInitStruct->ClockPolarity = LL_SPI_POLARITY_HIGH;
spiInitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
break;
case SPI_WORK_MODE_2:
spiInitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
spiInitStruct->ClockPhase = LL_SPI_PHASE_2EDGE;
break;
case SPI_WORK_MODE_3:
spiInitStruct->ClockPolarity = LL_SPI_POLARITY_HIGH;
spiInitStruct->ClockPhase = LL_SPI_PHASE_2EDGE;
break;
default:
spiInitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
spiInitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
}
spiInitStruct->NSS = g_nssMaps[resource->nss];
spiInitStruct->BaudRate = g_baudMaps[resource->baudRate];
if (resource->bitOrder == SPI_MSB_FIRST) {
spiInitStruct->BitOrder = LL_SPI_MSB_FIRST;
} else {
spiInitStruct->BitOrder = LL_SPI_LSB_FIRST;
}
if (resource->crcEnable == CRC_DISABLE) {
spiInitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
} else {
spiInitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_ENABLE;
}
spiInitStruct->CRCPoly = resource->crcPoly;
return;
}
static int32_t InitSpiDevice(SpiDevice *spiDevice)
{
uint32_t spiPort;
SpiResource *resource = NULL;
if (spiDevice == NULL) {
HDF_LOGE("%s: invalid parameter\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
LL_SPI_InitTypeDef spiInitStruct = {0};
resource = &spiDevice->resource;
spiPort = spiDevice->spiId;
EnableSpiClock(spiPort + 1);
InitSpiInitStruct(&spiInitStruct, resource);
SPI_TypeDef* spix = g_spiGroupMaps[resource->spix];
spiContext[spiPort].spix = spix;
LL_SPI_Disable(spix);
uint8_t ret = LL_SPI_Init(spix, &spiInitStruct);
if (ret != 0) {
HDF_LOGE("HAL INIT SPI FAILED\r\n");
return HDF_FAILURE;
}
if (resource->standard == SPI_PROTO_MOTOROLA) {
LL_SPI_SetStandard(spix, LL_SPI_PROTOCOL_MOTOROLA);
} else {
LL_SPI_SetStandard(spix, LL_SPI_PROTOCOL_TI);
}
return HDF_SUCCESS;
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#define SPI_FIND_CONFIG(node, name, resource, spiDevice) \
do { \
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
resource->busNum = HCS_PROP(node, busNum); \
spiDevice->spiId = resource->busNum; \
resource->csNum = HCS_PROP(node, csNum); \
resource->transDir = HCS_PROP(node, transDir); \
resource->transMode = HCS_PROP(node, transMode); \
resource->smMode = HCS_PROP(node, smMode); \
resource->dataWidth = HCS_PROP(node, dataWidth); \
resource->clkMode = HCS_PROP(node, clkMode); \
resource->csNum = HCS_PROP(node, csNum); \
resource->nss = HCS_PROP(node, nss); \
resource->baudRate = HCS_PROP(node, baudRate); \
resource->bitOrder = HCS_PROP(node, bitOrder); \
resource->crcEnable = HCS_PROP(node, crcEnable); \
resource->crcPoly = HCS_PROP(node, crcPoly); \
resource->spix = HCS_PROP(node, spix); \
resource->csPin = HCS_PROP(node, csPin); \
resource->csGroup = HCS_PROP(node, csGpiox); \
resource->standard = HCS_PROP(node, standard); \
resource->dummyByte = HCS_PROP(node, dummyByte); \
result = HDF_SUCCESS; \
} \
} while (0)
#define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
#define PLATFORM_SPI_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), spi_config)
static int32_t GetSpiDeviceResource(SpiDevice *spiDevice, const char *deviceMatchAttr)
{
int32_t result = HDF_FAILURE;
SpiResource *resource = NULL;
if (spiDevice == NULL || deviceMatchAttr == NULL) {
HDF_LOGE("device or deviceMatchAttr is NULL\r\n");
return HDF_ERR_INVALID_PARAM;
}
resource = &spiDevice->resource;
#if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, spi_config)
HCS_FOREACH_CHILD_VARGS(PLATFORM_SPI_CONFIG, SPI_FIND_CONFIG, deviceMatchAttr, resource, spiDevice);
#endif
if (result != HDF_SUCCESS) {
HDF_LOGE("resourceNode %s is NULL\r\n", deviceMatchAttr);
}
return result;
}
#else
static int32_t GetSpiDeviceResource(SpiDevice *spiDevice, const struct DeviceResourceNode *resourceNode)
{
struct DeviceResourceIface *dri = NULL;
if (spiDevice == NULL || resourceNode == NULL) {
HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
SpiResource *resource = NULL;
resource = &spiDevice->resource;
if (resource == NULL) {
HDF_LOGE("%s: resource is NULL\r\n", __func__);
return HDF_ERR_INVALID_OBJECT;
}
dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); // open HDF
if (dri == NULL || dri->GetUint16 == NULL || dri->GetUint8 == NULL || dri->GetUint32 == NULL) {
HDF_LOGE("DeviceResourceIface is invalid\r\n");
return HDF_ERR_INVALID_PARAM;
}
uint8_t temp[HCS_UINT8_PARSE_NUM] = {0};
for (int i = 0; i < HCS_UINT8_PARSE_NUM; i++) {
if (dri->GetUint8(resourceNode, g_parseHcsMap[i], &temp[i], 0) != HDF_SUCCESS) {
HDF_LOGE("get config %s failed\r\n", g_parseHcsMap[i]);
return HDF_FAILURE;
}
}
int ret = memcpy_s(resource, HCS_UINT8_PARSE_NUM, temp, HCS_UINT8_PARSE_NUM);
if (ret != 0) {
HDF_LOGE("memcpy failed\r\n");
return HDF_FAILURE;
}
if (dri->GetUint16(resourceNode, "crcPoly", &resource->crcPoly, 0) != HDF_SUCCESS) {
HDF_LOGE("get config %s failed\r\n", "crcPoly");
return HDF_FAILURE;
}
spiDevice->spiId = resource->busNum;
return HDF_SUCCESS;
}
#endif
int32_t AttachSpiDevice(struct SpiCntlr *spiCntlr, struct HdfDeviceObject *device)
{
int32_t ret;
SpiDevice *spiDevice = NULL;
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
if (spiCntlr == NULL || device == NULL) {
#else
if (spiCntlr == NULL || device == NULL || device->property == NULL) {
#endif
HDF_LOGE("%s: property is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
spiDevice = (SpiDevice *)OsalMemAlloc(sizeof(SpiDevice));
if (spiDevice == NULL) {
HDF_LOGE("%s: OsalMemAlloc spiDevice error\r\n", __func__);
return HDF_ERR_MALLOC_FAIL;
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
ret = GetSpiDeviceResource(spiDevice, device->deviceMatchAttr);
#else
ret = GetSpiDeviceResource(spiDevice, device->property);
#endif
if (ret != HDF_SUCCESS) {
(void)OsalMemFree(spiDevice);
return HDF_FAILURE;
}
spiCntlr->priv = spiDevice;
spiCntlr->busNum = spiDevice->spiId;
InitSpiDevice(spiDevice);
return HDF_SUCCESS;
}
/* SPI Method */
static int32_t SpiDevGetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg);
static int32_t SpiDevSetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg);
static int32_t SpiDevTransfer(struct SpiCntlr *spiCntlr, struct SpiMsg *spiMsg, uint32_t count);
static int32_t SpiDevOpen(struct SpiCntlr *spiCntlr);
static int32_t SpiDevClose(struct SpiCntlr *spiCntlr);
struct SpiCntlrMethod g_twSpiCntlrMethod = {
.GetCfg = SpiDevGetCfg,
.SetCfg = SpiDevSetCfg,
.Transfer = SpiDevTransfer,
.Open = SpiDevOpen,
.Close = SpiDevClose,
};
/* HdfDriverEntry method definitions */
static int32_t SpiDriverBind(struct HdfDeviceObject *device);
static int32_t SpiDriverInit(struct HdfDeviceObject *device);
static void SpiDriverRelease(struct HdfDeviceObject *device);
/* HdfDriverEntry definitions */
struct HdfDriverEntry g_SpiDriverEntry = {
.moduleVersion = 1,
.moduleName = "ST_SPI_MODULE_HDF",
.Bind = SpiDriverBind,
.Init = SpiDriverInit,
.Release = SpiDriverRelease,
};
HDF_INIT(g_SpiDriverEntry);
static int32_t SpiDriverBind(struct HdfDeviceObject *device)
{
struct SpiCntlr *spiCntlr = NULL;
if (device == NULL) {
HDF_LOGE("Sample device object is null!\r\n");
return HDF_ERR_INVALID_PARAM;
}
HDF_LOGI("Enter %s:\r\n", __func__);
spiCntlr = SpiCntlrCreate(device);
if (spiCntlr == NULL) {
HDF_LOGE("SpiCntlrCreate object is null!\r\n");
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t SpiDriverInit(struct HdfDeviceObject *device)
{
int32_t ret;
struct SpiCntlr *spiCntlr = NULL;
if (device == NULL) {
HDF_LOGE("%s: device is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
HDF_LOGI("Enter %s:", __func__);
spiCntlr = SpiCntlrFromDevice(device);
if (spiCntlr == NULL) {
HDF_LOGE("%s: spiCntlr is NULL", __func__);
return HDF_DEV_ERR_NO_DEVICE;
}
ret = AttachSpiDevice(spiCntlr, device); // SpiCntlr add TWSpiDevice to priv
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: attach error\r\n", __func__);
return HDF_DEV_ERR_ATTACHDEV_FAIL;
}
spiCntlr->method = &g_twSpiCntlrMethod; // register callback
return ret;
}
static void SpiDriverRelease(struct HdfDeviceObject *device)
{
struct SpiCntlr *spiCntlr = NULL;
SpiDevice *spiDevice = NULL;
HDF_LOGI("Enter %s\r\n", __func__);
if (device == NULL) {
HDF_LOGE("%s: device is NULL\r\n", __func__);
return;
}
spiCntlr = SpiCntlrFromDevice(device);
if (spiCntlr == NULL || spiCntlr->priv == NULL) {
HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
return;
}
spiDevice = (SpiDevice *)spiCntlr->priv;
OsalMemFree(spiDevice);
return;
}
static int32_t SpiDevOpen(struct SpiCntlr *spiCntlr)
{
HDF_LOGI("Enter %s\r\n", __func__);
uint32_t spiPort;
SpiDevice *spiDevice = NULL;
spiDevice = (SpiDevice*)spiCntlr->priv;
spiPort = spiDevice->spiId;
SPI_TypeDef* spix = g_spiGroupMaps[spiDevice->resource.spix];
LL_SPI_Enable(spix);
return HDF_SUCCESS;
}
static int32_t SpiDevClose(struct SpiCntlr *spiCntlr)
{
uint32_t spiPort;
SpiDevice *spiDevice = NULL;
spiDevice = (SpiDevice*)spiCntlr->priv;
spiPort = spiDevice->spiId;
SPI_TypeDef* spix = g_spiGroupMaps[spiDevice->resource.spix];
LL_SPI_Disable(spix);
return HDF_SUCCESS;
}
static int32_t SpiDevGetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg)
{
SpiDevice *spiDevice = NULL;
if (spiCntlr == NULL || spiCfg == NULL || spiCntlr->priv == NULL) {
HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
spiDevice = (SpiDevice *)spiCntlr->priv;
if (spiDevice == NULL) {
return HDF_DEV_ERR_NO_DEVICE;
}
spiCfg->maxSpeedHz = spiDevice->resource.baudRate;
spiCfg->mode = spiDevice->resource.clkMode;
spiCfg->transferMode = spiDevice->resource.transMode;
spiCfg->bitsPerWord = spiDevice->resource.dataWidth;
if (spiDevice->resource.dataWidth) {
spiCfg->bitsPerWord = BITWORD_SIXTEEN;
} else {
spiCfg->bitsPerWord = BITWORD_EIGHT;
}
return HDF_SUCCESS;
}
static int32_t SpiDevSetCfg(struct SpiCntlr *spiCntlr, struct SpiCfg *spiCfg)
{
SpiDevice *spiDevice = NULL;
if (spiCntlr == NULL || spiCfg == NULL || spiCntlr->priv == NULL) {
HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
spiDevice = (SpiDevice *)spiCntlr->priv;
if (spiDevice == NULL) {
HDF_LOGE("%s: spiDevice is NULL\r\n", __func__);
return HDF_DEV_ERR_NO_DEVICE;
}
spiDevice->resource.baudRate = spiCfg->maxSpeedHz;
spiDevice->resource.clkMode = spiCfg->mode;
spiDevice->resource.transMode = spiCfg->transferMode;
if (spiCfg->bitsPerWord == BITWORD_EIGHT) {
spiDevice->resource.dataWidth = SPI_DATA_WIDTH_8;
} else {
spiDevice->resource.dataWidth = SPI_DATA_WIDTH_16;
}
return InitSpiDevice(spiDevice);
}
static int32_t SpiDevTransfer(struct SpiCntlr *spiCntlr, struct SpiMsg *spiMsg, uint32_t count)
{
uint32_t spiId;
SpiDevice *spiDevice = NULL;
uint32_t ticks = 0;
uint8_t singleCsChange = 0;
struct SpiMsg *msg = NULL;
if (spiCntlr == NULL || spiCntlr->priv == NULL) {
HDF_LOGE("%s: spiCntlr is NULL\r\n", __func__);
return HDF_ERR_INVALID_PARAM;
}
spiDevice = (SpiDevice *)spiCntlr->priv;
spiId = spiDevice->spiId;
for (size_t i = 0; i < count; i++) {
msg = &spiMsg[i];
LL_GPIO_ResetOutputPin(LL_GET_GPIOX(spiDevice->resource.csGroup), LL_GET_HAL_PIN(spiDevice->resource.csPin));
if ((msg->rbuf == NULL) && (msg->wbuf != NULL)) {
singleCsChange = msg->wbuf[0];
if (msg->len == 1) {
goto CS_DOWN;
}
HalSpiSend(spiDevice, msg->wbuf + 1, msg->len - 1);
}
if ((msg->rbuf != NULL) && (msg->wbuf == NULL)) {
singleCsChange = msg->rbuf[0];
if (msg->len == 1) {
goto CS_DOWN;
}
HalSpiRecv(spiDevice, msg->rbuf + 1, msg->len - 1);
}
if ((msg->wbuf != NULL) && (msg->rbuf != NULL)) {
HalSpiSendRecv(spiDevice, msg->wbuf, msg->len, msg->rbuf, msg->len);
}
if (msg->csChange || singleCsChange) {
LL_GPIO_SetOutputPin(LL_GET_GPIOX(spiDevice->resource.csGroup), LL_GET_HAL_PIN(spiDevice->resource.csPin));
}
if (msg->delayUs > 0) {
ticks = (msg->delayUs / PER_MS_IN_SEC);
osDelay(ticks);
}
}
return HDF_SUCCESS;
CS_DOWN:
if (msg->csChange || singleCsChange) {
LL_GPIO_SetOutputPin(LL_GET_GPIOX(spiDevice->resource.csGroup), LL_GET_HAL_PIN(spiDevice->resource.csPin));
}
return HDF_SUCCESS;
}
+7
View File
@@ -25,10 +25,17 @@ hdf_driver(module_name) {
if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) {
sources += [ "uart_wm.c" ]
}
if (defined(LOSCFG_SOC_SERIES_STM32F4xx)) {
sources += [ "uart_stm32f4xx.c" ]
}
include_dirs = [ "." ]
if (defined(LOSCFG_SHIELD_V200ZR_EVB_T1) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/fnlink/shields" ]
}
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
File diff suppressed because it is too large Load Diff
+4
View File
@@ -26,4 +26,8 @@ hdf_driver(module_name) {
}
include_dirs = [ "." ]
if (defined(LOSCFG_NIOBE407_USE_HDF) &&
defined(LOSCFG_DRIVERS_HDF_CONFIG_MACRO)) {
deps = [ "//device/board/talkweb/niobe407/liteos_m/hdf_config" ]
}
}
+46 -3
View File
@@ -8,7 +8,12 @@
#include <stdlib.h>
#include <stdio.h>
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#include "hcs_macro.h"
#include "hdf_config_macro.h"
#else
#include "device_resource_if.h"
#endif
#include "hdf_device_desc.h"
#include "hdf_log.h"
#include "watchdog_core.h"
@@ -54,6 +59,35 @@ static int InitWatchdogDeviceInfo(WatchdogDeviceInfo *watchdogdeviceinfo)
return HDF_SUCCESS;
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
#define WATCHDOG_FIND_CONFIG(node, name, device) \
do { \
if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
device->watchdogId = HCS_PROP(node, id); \
device->timeout = HCS_PROP(node, timeout); \
result = HDF_SUCCESS; \
} \
} while (0)
#define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
#define PLATFORM_WATCHDOG_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), watchdog_config)
static uint32_t GetWatchdogDeviceInfoResource(WatchdogDeviceInfo *device, const char *deviceMatchAttr)
{
int32_t result = HDF_FAILURE;
if (device == NULL || deviceMatchAttr == NULL) {
HDF_LOGE("device or deviceMatchAttr is NULL\r\n");
return HDF_ERR_INVALID_PARAM;
}
#if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, watchdog_config)
HCS_FOREACH_CHILD_VARGS(PLATFORM_WATCHDOG_CONFIG, WATCHDOG_FIND_CONFIG, deviceMatchAttr, device);
#endif
if (result != HDF_SUCCESS) {
HDF_LOGE("resourceNode %s is NULL\r\n", deviceMatchAttr);
return result;
}
return HDF_SUCCESS;
}
#else
static uint32_t GetWatchdogDeviceInfoResource(WatchdogDeviceInfo *device, const struct DeviceResourceNode *resourceNode)
{
struct DeviceResourceIface *dri = NULL;
@@ -76,19 +110,24 @@ static uint32_t GetWatchdogDeviceInfoResource(WatchdogDeviceInfo *device, const
HDF_LOGE("read watchdogId fail\r\n");
return HDF_FAILURE;
}
HDF_LOGI("watchdogId = %d\n", device->watchdogId);
HDF_LOGI("timeout = %dms\n", device->timeout);
return HDF_SUCCESS;
}
#endif
static int32_t AttachWatchdogDeviceInfo(struct WatchdogCntlr *watchdogCntlr, struct HdfDeviceObject *device)
{
int32_t ret;
WatchdogDeviceInfo *watchdogdeviceinfo = NULL;
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
if (device == NULL || device->deviceMatchAttr == NULL) {
#else
if (device == NULL || device->property == NULL) {
#endif
HDF_LOGE("%s: param is NULL\r\n", __func__);
return HDF_FAILURE;
}
@@ -99,7 +138,11 @@ static int32_t AttachWatchdogDeviceInfo(struct WatchdogCntlr *watchdogCntlr, str
return HDF_ERR_MALLOC_FAIL;
}
#ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
ret = GetWatchdogDeviceInfoResource(watchdogdeviceinfo, device->deviceMatchAttr);
#else
ret = GetWatchdogDeviceInfoResource(watchdogdeviceinfo, device->property);
#endif
if (ret != HDF_SUCCESS) {
(void)OsalMemFree(watchdogdeviceinfo);
return HDF_FAILURE;
@@ -177,7 +220,7 @@ static int32_t WatchdogDriverInit(struct HdfDeviceObject *device)
}
watchdogCntlr->ops = &g_WatchdogCntlrMethod;
HDF_LOGI("WatchdogDriverInit success!\r\n");
return ret;
}