提交 7c45b3a2 编写于 作者: Y yinshuqing

New Mipi_ CSI guidance document

Signed-off-by: Nyinshuqing <yinshuqing@huawei.com>
上级 d833559b
/*
* Copyright (c) 2021 Huawei Device 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.
*/
/**
* @addtogroup ADC
* @{
*
* @brief 定义用于模/数转换器驱动程序开发的标准ADC API。
* 此ADC模块抽象了不同系统平台的ADC功能,以提供稳定的API,用于模/数转换器驱动程序开发。您可以使用此模块获取/释放ADC设备句柄。
*
* @since 1.0
*/
/**
* @file adc_if.h
*
* @brief 声明标准ADC接口函数。
*
* @since 1.0
*/
#ifndef ADC_IF_H
#define ADC_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
struct AdcIoMsg {
/** ADC设备号 */
uint32_t number;
/** ADC设备通道号 */
uint32_t channel;
};
/**
* @brief 获取ADC设备的句柄。
* 在访问ADC设备之前,必须调用此函数。
*
* @param number ADC设备ID。
*
* @return 如果操作成功,则返回指向ADC设备的DevHandle的指针;否则返回NULL。
*
* @since 1.0
*/
DevHandle AdcOpen(uint32_t number);
/**
* @brief 释放ADC设备的句柄。
* 如果不再需要访问ADC设备,则应调用此函数关闭其句柄,以便释放未使用的内存资源。
*
* @param handle 指向通过{@link AdcOpen}获得的ADC设备的设备句柄的指针。
*
* @since 1.0
*/
void AdcClose(DevHandle handle);
/**
* @brief 从ADC设备读取指定大小的数据。
*
* @param handle 指向通过{@link AdcOpen}获得的ADC设备的设备句柄的指针。
* @param channel ADC设备通道。
* @param val 指向存储读出数据指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
* @since 1.0
*/
int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* ADC_IF_H */
/*
* Copyright (c) 2021 Huawei Device 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.
*/
/**
* @addtogroup HDMI
* @{
*
* @brief 声明基本高清多媒体接口(HDMI)功能的标准API。
* 您可以使用此模块访问HDMI,并使驱动程序能够操作HDMI接收器设备。
* 这些功能包括在HDMI上启动和停止传输,设置一些属性,并读取接收器设备的EDID数据。
*
* @since 1.0
*/
/**
* @file hdmi_if.h
*
* @brief 声明标准HDMI接口函数。
*
* @since 1.0
*/
#ifndef HDMI_IF_H
#define HDMI_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/**
* @brief HDMI接收器设备的EDID的最大长度为512字节。
*
* @since 1.0
*/
#define HDMI_EDID_MAX_LEN 512
/**
* @brief 色深
* 详见HDMI协议1.4第6.2.4节。
*
* @since 1.0
*/
enum HdmiDeepColor {
HDMI_DEEP_COLOR_24BITS = 0,
HDMI_DEEP_COLOR_30BITS = 1,
HDMI_DEEP_COLOR_36BITS = 2,
HDMI_DEEP_COLOR_48BITS = 3,
HDMI_DEEP_COLOR_OFF = 0xff,
HDMI_DEEP_COLOR_BUTT,
};
/**
* @brief 视频位深度。
* 详见HDMI协议1.4第6.6节。
*
* @since 1.0
*/
enum HdmiVideoBitDepth {
HDMI_VIDEO_BIT_DEPTH_8 = 0,
HDMI_VIDEO_BIT_DEPTH_10 = 1,
HDMI_VIDEO_BIT_DEPTH_12 = 2,
HDMI_VIDEO_BIT_DEPTH_16 = 3,
HDMI_VIDEO_BIT_DEPTH_OFF,
};
/**
* @brief 色彩空间。
* 详见HDMI协议1.4第6节。
*
* @since 1.0
*/
enum HdmiColorSpace {
HDMI_COLOR_SPACE_RGB = 0,
HDMI_COLOR_SPACE_YCBCR422 = 1,
HDMI_COLOR_SPACE_YCBCR444 = 2,
HDMI_COLOR_SPACE_YCBCR420 = 3,
HDMI_COLOR_SPACE_BUTT,
};
/**
* @brief 比色法。
* 详见HDMI协议1.4第6.7节和HDMI协议2.0第7.2节。
*
* @since 1.0
*/
enum HdmiColorimetry {
HDMI_COLORIMETRY_NO_DATA = 0,
HDMI_COLORIMETRY_ITU601 = 1,
HDMI_COLORIMETRY_ITU709 = 2,
HDMI_COLORIMETRY_EXTENDED = 3,
};
/**
* @brief 扩展比色法。
* 详见HDMI协议1.4第6.7节和HDMI协议2.0第7.2节。
*
* @since 1.0
*/
enum HdmiExtendedColorimetry {
HDMI_EXTENDED_COLORIMETRY_XV_YCC_601 = 0,
HDMI_EXTENDED_COLORIMETRY_XV_YCC_709 = 1,
HDMI_EXTENDED_COLORIMETRY_S_YCC_601 = 2,
HDMI_EXTENDED_COLORIMETRY_OPYCC_601 = 3,
HDMI_EXTENDED_COLORIMETRY_OPRGB = 4,
HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM = 5,
HDMI_EXTENDED_COLORIMETRY_BT2020 = 6,
HDMI_EXTENDED_COLORIMETRY_ADDITIONAL = 7,
HDMI_EXTENDED_COLORIMETRY_BUTT,
};
/**
* @brief 量化范围。
* 详见HDMI协议1.4第6.6节和HDMI协议2.0第7.3节。
*
* @since 1.0
*/
enum HdmiQuantizationRange {
HDMI_QUANTIZATION_RANGE_DEFAULT = 0,
HDMI_QUANTIZATION_RANGE_LIMITED = 1,
HDMI_QUANTIZATION_RANGE_FULL = 2,
HDMI_QUANTIZATION_RANGE_BUTT,
};
/**
* @brief YCC量化范围。
* 详见HDMI协议1.4第6.6节和HDMI协议2.0第7.3节。
*
* @since 1.0
*/
enum HdmiYccQuantizationRange {
HDMI_YCC_QUANTIZATION_RANGE_LIMITED = 0,
HDMI_YCC_QUANTIZATION_RANGE_FULL = 1,
HDMI_YCC_QUANTIZATION_RANGE_BUTT,
};
/**
* @brief 视频三维结构。
* 详见HDMI协议1.4第8.2.3节。
*
* @since 1.0
*/
enum HdmiVideo3dStructure {
HDMI_VS_VIDEO_3D_FRAME_PACKING = 0,
HDMI_VS_VIDEO_3D_FIELD_ALTERNATIVE = 1,
HDMI_VS_VIDEO_3D_LINE_ALTERNATIVE = 2,
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_FULL = 3,
HDMI_VS_VIDEO_3D_L_DEPTH = 4,
HDMI_VS_VIDEO_3D_L_DEPTH_GFX_GFX_DEPTH = 5,
HDMI_VS_VIDEO_3D_TOP_AND_BOTTOM = 6,
HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_HALF = 8,
HDMI_VS_VIDEO_3D_BUTT,
};
/**
* @brief 影像时序。
* 详见HDMI协议1.4第8.2.3节。
*
* @since 1.0
*/
enum HdmiVideoTiming {
HDMI_VIDEO_TIMING_NONE = 0,
HDMI_VIDEO_TIMING_640X480P60 = 1,
HDMI_VIDEO_TIMING_720X480P60 = 2,
HDMI_VIDEO_TIMING_720X480P120 = 3,
HDMI_VIDEO_TIMING_720X480P240 = 4,
HDMI_VIDEO_TIMING_720X576P50 = 5,
HDMI_VIDEO_TIMING_720X576P100 = 6,
HDMI_VIDEO_TIMING_720X576P200 = 7,
HDMI_VIDEO_TIMING_1280X720P24 = 8,
HDMI_VIDEO_TIMING_1280X720P25 = 9,
HDMI_VIDEO_TIMING_1280X720P30 = 10,
HDMI_VIDEO_TIMING_1280X720P48 = 11,
HDMI_VIDEO_TIMING_1280X720P50 = 12,
HDMI_VIDEO_TIMING_1280X720P60 = 13,
HDMI_VIDEO_TIMING_1280X720P100 = 14,
HDMI_VIDEO_TIMING_1280X720P120 = 15,
HDMI_VIDEO_TIMING_1440X240P60 = 16,
HDMI_VIDEO_TIMING_1440X288P50 = 17,
HDMI_VIDEO_TIMING_1440X480I60 = 18,
HDMI_VIDEO_TIMING_1440X480P60 = 19,
HDMI_VIDEO_TIMING_1440X480I120 = 20,
HDMI_VIDEO_TIMING_1440X480I240 = 21,
HDMI_VIDEO_TIMING_1440X576I50 = 22,
HDMI_VIDEO_TIMING_1440X576P50 = 23,
HDMI_VIDEO_TIMING_1440X576I60 = 24,
HDMI_VIDEO_TIMING_1440X576I100 = 25,
HDMI_VIDEO_TIMING_1440X576I200 = 26,
HDMI_VIDEO_TIMING_2880X288P50 = 27,
HDMI_VIDEO_TIMING_2880X480I60 = 28,
HDMI_VIDEO_TIMING_2880X480P60 = 29,
HDMI_VIDEO_TIMING_2880X240I60 = 30,
HDMI_VIDEO_TIMING_2880X576I50 = 31,
HDMI_VIDEO_TIMING_2880X576P50 = 32,
HDMI_VIDEO_TIMING_1680X720P24 = 33,
HDMI_VIDEO_TIMING_1680X720P25 = 34,
HDMI_VIDEO_TIMING_1680X720P30 = 35,
HDMI_VIDEO_TIMING_1680X720P48 = 36,
HDMI_VIDEO_TIMING_1680X720P50 = 37,
HDMI_VIDEO_TIMING_1680X720P60 = 38,
HDMI_VIDEO_TIMING_1680X720P100 = 39,
HDMI_VIDEO_TIMING_1680X720P120 = 40,
HDMI_VIDEO_TIMING_2560X1080P24 = 41,
HDMI_VIDEO_TIMING_2560X1080P25 = 42,
HDMI_VIDEO_TIMING_2560X1080P30 = 43,
HDMI_VIDEO_TIMING_2560X1080P48 = 44,
HDMI_VIDEO_TIMING_2560X1080P50 = 45,
HDMI_VIDEO_TIMING_2560X1080P60 = 46,
HDMI_VIDEO_TIMING_2560X1080P100 = 47,
HDMI_VIDEO_TIMING_2560X1080P120 = 48,
HDMI_VIDEO_TIMING_1920X1080I60 = 49,
HDMI_VIDEO_TIMING_1920X1080P60 = 50,
HDMI_VIDEO_TIMING_1920X1080I50 = 51,
HDMI_VIDEO_TIMING_1920X1080P50 = 52,
HDMI_VIDEO_TIMING_1920X1080P24 = 53,
HDMI_VIDEO_TIMING_1920X1080P25 = 54,
HDMI_VIDEO_TIMING_1920X1080P30 = 55,
HDMI_VIDEO_TIMING_1920X1080P48 = 56,
HDMI_VIDEO_TIMING_1920X1080I100 = 57,
HDMI_VIDEO_TIMING_1920X1080I120 = 58,
HDMI_VIDEO_TIMING_1920X1080P120 = 59,
HDMI_VIDEO_TIMING_1920X1080P100 = 60,
HDMI_VIDEO_TIMING_3840X2160P24 = 61,
HDMI_VIDEO_TIMING_3840X2160P25 = 62,
HDMI_VIDEO_TIMING_3840X2160P30 = 63,
HDMI_VIDEO_TIMING_3840X2160P48 = 64,
HDMI_VIDEO_TIMING_3840X2160P50 = 65,
HDMI_VIDEO_TIMING_3840X2160P60 = 66,
HDMI_VIDEO_TIMING_3840X2160P100 = 67,
HDMI_VIDEO_TIMING_3840X2160P120 = 68,
HDMI_VIDEO_TIMING_4096X2160P24 = 69,
HDMI_VIDEO_TIMING_4096X2160P25 = 70,
HDMI_VIDEO_TIMING_4096X2160P30 = 71,
HDMI_VIDEO_TIMING_4096X2160P48 = 72,
HDMI_VIDEO_TIMING_4096X2160P50 = 73,
HDMI_VIDEO_TIMING_4096X2160P60 = 74,
HDMI_VIDEO_TIMING_4096X2160P100 = 75,
HDMI_VIDEO_TIMING_4096X2160P120 = 76,
HDMI_VIDEO_TIMING_5120X2160P24 = 77,
HDMI_VIDEO_TIMING_5120X2160P25 = 78,
HDMI_VIDEO_TIMING_5120X2160P30 = 79,
HDMI_VIDEO_TIMING_5120X2160P48 = 80,
HDMI_VIDEO_TIMING_5120X2160P50 = 81,
HDMI_VIDEO_TIMING_5120X2160P60 = 82,
HDMI_VIDEO_TIMING_5120X2160P100 = 83,
HDMI_VIDEO_TIMING_5120X2160P120 = 84,
HDMI_VIDEO_TIMING_7680X4320P24 = 85,
HDMI_VIDEO_TIMING_7680X4320P25 = 86,
HDMI_VIDEO_TIMING_7680X4320P30 = 87,
HDMI_VIDEO_TIMING_7680X4320P48 = 88,
HDMI_VIDEO_TIMING_7680X4320P50 = 89,
HDMI_VIDEO_TIMING_7680X4320P60 = 90,
HDMI_VIDEO_TIMING_7680X4320P100 = 91,
HDMI_VIDEO_TIMING_7680X4320P120 = 92,
HDMI_VIDEO_TIMING_10240X4320P24 = 93,
HDMI_VIDEO_TIMING_10240X4320P25 = 94,
HDMI_VIDEO_TIMING_10240X4320P30 = 95,
HDMI_VIDEO_TIMING_10240X4320P48 = 96,
HDMI_VIDEO_TIMING_10240X4320P50 = 97,
HDMI_VIDEO_TIMING_10240X4320P60 = 98,
HDMI_VIDEO_TIMING_10240X4320P100 = 99,
HDMI_VIDEO_TIMING_10240X4320P120 = 100,
HDMI_VIDEO_TIMING_VESA_DEFINE = 101,
HDMI_VIDEO_TIMING_VESA_800X600_60 = 102,
HDMI_VIDEO_TIMING_VESA_848X480_60 = 103,
HDMI_VIDEO_TIMING_VESA_1024X768_60 = 104,
HDMI_VIDEO_TIMING_VESA_1280X720_60 = 105,
HDMI_VIDEO_TIMING_VESA_1280X768_60 = 106,
HDMI_VIDEO_TIMING_VESA_1280X768_60_RB = 107,
HDMI_VIDEO_TIMING_VESA_1280X800_60 = 108,
HDMI_VIDEO_TIMING_VESA_1280X800_60_RB = 109,
HDMI_VIDEO_TIMING_VESA_1280X960_60 = 110,
HDMI_VIDEO_TIMING_VESA_1280X1024_60 = 111,
HDMI_VIDEO_TIMING_VESA_1360X768_60 = 112,
HDMI_VIDEO_TIMING_VESA_1366X768_60 = 113,
HDMI_VIDEO_TIMING_VESA_1400X1050_60 = 114,
HDMI_VIDEO_TIMING_VESA_1440X900_60 = 115,
HDMI_VIDEO_TIMING_VESA_1440X900_60_RB = 116,
HDMI_VIDEO_TIMING_VESA_1440X1050_60 = 117,
HDMI_VIDEO_TIMING_VESA_1440X1050_60_RB = 118,
HDMI_VIDEO_TIMING_VESA_1600X900_60_RB = 119,
HDMI_VIDEO_TIMING_VESA_1600X1200_60 = 120,
HDMI_VIDEO_TIMING_VESA_1680X1050_60 = 113,
HDMI_VIDEO_TIMING_VESA_1680X1050_60_RB = 114,
HDMI_VIDEO_TIMING_VESA_1792X1344_60 = 115,
HDMI_VIDEO_TIMING_VESA_1856X1392_60 = 116,
HDMI_VIDEO_TIMING_VESA_1920X1080_60 = 117,
HDMI_VIDEO_TIMING_VESA_1920X1200_60 = 118,
HDMI_VIDEO_TIMING_VESA_1920X1200_60_RB = 119,
HDMI_VIDEO_TIMING_VESA_1920X1440_60 = 120,
HDMI_VIDEO_TIMING_VESA_2048X1152_60 = 121,
HDMI_VIDEO_TIMING_VESA_2560X1440_60_RB = 122,
HDMI_VIDEO_TIMING_VESA_2560X1600_60 = 123,
HDMI_VIDEO_TIMING_VESA_2560X1600_60_RB = 124,
HDMI_VIDEO_TIMING_USER_DEFINE = 125,
HDMI_VIDEO_TIMING_USER_1920X2160_30 = 126,
HDMI_VIDEO_TIMING_USER_2560X1440_30 = 127,
HDMI_VIDEO_TIMING_USER_2560X1440_60 = 128,
HDMI_VIDEO_TIMING_USER_1280X720_60 = 129,
HDMI_VIDEO_TIMING_USER_1366X768_60 = 130,
HDMI_VIDEO_TIMING_USER_1600X900_60_RB = 131,
HDMI_VIDEO_TIMING_USER_1920X1080_60 = 132,
HDMI_VIDEO_TIMING_USER_2048X1152_60 = 133,
HDMI_VIDEO_TIMING_BUTT,
};
/**
* @brief 图片的纵横比。
* 详见HDMI协议1.4第8.2.1节。
*
* @since 1.0
*/
enum HdmiPictureAspectRatio {
HDMI_PICTURE_ASPECT_NO_DATA = 0,
HDMI_PICTURE_ASPECT_4_3 = 1,
HDMI_PICTURE_ASPECT_16_9 = 2,
HDMI_PICTURE_ASPECT_64_27 = 3,
HDMI_PICTURE_ASPECT_256_135 = 4,
HDMI_PICTURE_ASPECT_BUTT = 5,
};
/**
* @brief 活动格式的长宽比。
* 详见HDMI协议1.4第8.2.1节。
*
* @since 1.0
*/
enum HdmiActiveFormatAspectRatio {
HDMI_ACTIVE_FORMAT_ASPECT_16_9_TOP = 2,
HDMI_ACTIVE_FORMAT_ASPECT_14_9_TOP = 3,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_CENTER = 4,
HDMI_ACTIVE_FORMAT_ASPECT_PICTURE = 8,
HDMI_ACTIVE_FORMAT_ASPECT_4_3 = 9,
HDMI_ACTIVE_FORMAT_ASPECT_16_9 = 10,
HDMI_ACTIVE_FORMAT_ASPECT_14_9 = 11,
HDMI_ACTIVE_FORMAT_ASPECT_4_3_SP_14_9 = 13,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_14_9 = 14,
HDMI_ACTIVE_FORMAT_ASPECT_16_9_SP_4_3 = 15,
HDMI_ACTIVE_FORMAT_ASPECT_BUTT,
};
/**
* @brief NUP(非均匀图片缩放)。
* 详见HDMI协议1.4第8.2.1节。
*
* @since 1.0
*/
enum HdmiNups {
HDMI_NUPS_UNKNOWN = 0, /* 没有已知的非均匀缩放 */
HDMI_NUPS_HORIZONTAL = 1, /* 图片已水平缩放 */
HDMI_NUPS_VERTICAL = 2, /* 图片已垂直缩放 */
HDMI_NUPS_BOTH = 3, /* 图片已水平和垂直缩放 */
};
/**
* @brief 定义视频属性结构。
*
* @since 1.0
*/
struct HdmiVideoAttr {
uint32_t tmdsClock; /* 单位:千赫 */
uint32_t pixelClock; /* 单位:千赫 */
uint32_t pixelRepeat;
enum HdmiColorSpace colorSpace;
enum HdmiColorimetry colorimetry;
enum HdmiExtendedColorimetry extColorimetry;
enum HdmiQuantizationRange quantization;
enum HdmiYccQuantizationRange yccQuantization;
enum HdmiDeepColor deepColor;
enum HdmiVideo3dStructure _3dStruct;
enum HdmiVideoTiming timing;
enum HdmiPictureAspectRatio aspect;
enum HdmiActiveFormatAspectRatio activeAspect;
enum HdmiNups nups;
bool xvycc;
};
/**
* @brief 音频编码类型。
* 详见HDMI协议1.4第7节。
*
* @since 1.0
*/
enum HdmiAudioCodingType {
HDMI_AUDIO_CODING_TYPE_STREAM = 0,
HDMI_AUDIO_CODING_TYPE_LPCM = 1,
HDMI_AUDIO_CODING_TYPE_AC3 = 2,
HDMI_AUDIO_CODING_TYPE_MPEG1 = 3,
HDMI_AUDIO_CODING_TYPE_MP3 = 4,
HDMI_AUDIO_CODING_TYPE_MPEG2 = 5,
HDMI_AUDIO_CODING_TYPE_AAC_LC = 6,
HDMI_AUDIO_CODING_TYPE_DTS = 7,
HDMI_AUDIO_CODING_TYPE_ATRAC = 8,
HDMI_AUDIO_CODING_TYPE_OBA = 9,
HDMI_AUDIO_CODING_TYPE_EAC3 = 10,
HDMI_AUDIO_CODING_TYPE_DTS_HD = 11,
HDMI_AUDIO_CODING_TYPE_MLP = 12,
HDMI_AUDIO_CODING_TYPE_DST = 13,
HDMI_AUDIO_CODING_TYPE_WMA_PRO = 14,
HDMI_AUDIO_CODING_TYPE_CXT = 15,
};
/**
* @brief 音频接口类型。
*
* @since 1.0
*/
enum HdmiAudioInterfaceType {
HDMI_AUDIO_IF_TYPE_I2S = 0, /* I2S总线 */
HDMI_AUDIO_IF_TYPE_SPDIF = 1, /* 索尼/飞利浦数字接口 */
HDMI_AUDIO_IF_TYPE_OTHER,
};
/**
* @brief 音频位深度。
* 详见HDMI协议1.4第7节。
*
* @since 1.0
*/
enum HdmiAudioBitDepth {
HDMI_ADIO_BIT_DEPTH_UNKNOWN,
HDMI_ADIO_BIT_DEPTH_8 = 8,
HDMI_ADIO_BIT_DEPTH_16 = 16,
HDMI_ADIO_BIT_DEPTH_18 = 18,
HDMI_ADIO_BIT_DEPTH_20 = 20,
HDMI_ADIO_BIT_DEPTH_24 = 24,
HDMI_ADIO_BIT_DEPTH_32 = 32,
HDMI_ADIO_BIT_DEPTH_BUTT,
};
/**
* @brief 用于音频的采样率。
* 详见HDMI协议1.4第7.3节。
*
* @since 1.0
*/
enum HdmiSampleRate {
HDMI_SAMPLE_RATE_UNKNOWN,
HDMI_SAMPLE_RATE_8K = 8000,
HDMI_SAMPLE_RATE_11K = 11025,
HDMI_SAMPLE_RATE_12K = 12000,
HDMI_SAMPLE_RATE_16K = 16000,
HDMI_SAMPLE_RATE_22K = 22050,
HDMI_SAMPLE_RATE_24K = 24000,
HDMI_SAMPLE_RATE_32K = 32000,
HDMI_SAMPLE_RATE_44K = 44100,
HDMI_SAMPLE_RATE_48K = 48000,
HDMI_SAMPLE_RATE_88K = 88200,
HDMI_SAMPLE_RATE_96K = 96000,
HDMI_SAMPLE_RATE_176K = 176400,
HDMI_SAMPLE_RATE_192K = 192000,
HDMI_SAMPLE_RATE_768K = 768000,
HDMI_SAMPLE_RATE_BUTT,
};
/**
* @brief 音频格式通道。
* 详见HDMI协议1.4第7节。
*
* @since 1.0
*/
enum HdmiAudioFormatChannel {
HDMI_AUDIO_FORMAT_CHANNEL_2 = 2,
HDMI_AUDIO_FORMAT_CHANNEL_3,
HDMI_AUDIO_FORMAT_CHANNEL_4,
HDMI_AUDIO_FORMAT_CHANNEL_5,
HDMI_AUDIO_FORMAT_CHANNEL_6,
HDMI_AUDIO_FORMAT_CHANNEL_7,
HDMI_AUDIO_FORMAT_CHANNEL_8,
HDMI_AUDIO_FORMAT_CHANNEL_BUTT,
};
/**
* @brief 定义音频属性结构。
*
* @since 1.0
*/
struct HdmiAudioAttr {
enum HdmiAudioCodingType codingType;
enum HdmiAudioInterfaceType ifType;
enum HdmiAudioBitDepth bitDepth;
enum HdmiSampleRate sampleRate;
bool downSample;
enum HdmiAudioFormatChannel channels;
};
/**
* @brief 电光传递函数(EOTF)。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
enum HdmiEotfType {
HDMI_EOTF_SDR_LUMIN = 0, /* 传统gamma-SDR亮度范围 */
HDMI_EOTF_HDR_LUMIN = 1, /* 传统gamma-HDR亮度范围 */
HDMI_EOTF_SMPTE_ST_2048 = 2, /* SMPTE ST 2048 */
HDMI_EOTF_HLG = 3, /* 基于ITU-R BT.2100-0的混合对数伽马(HLG) */
HDMI_EOTF_BUTT,
};
/**
* @brief hdr色度计。
* 详见HDMI协议2.1。
*
* @since 1.0
*/
enum HdmiHdrColormetry {
HDMI_HDR_COLORIMETRY_NONE,
HDMI_HDR_COLORIMETRY_ITU_601,
HDMI_HDR_COLORIMETRY_ITU_709,
HDMI_HDR_COLORIMETRY_EXTENDED,
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_709,
HDMI_HDR_EXTENDED_COLORIMETRY_S_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
HDMI_HDR_EXTENDED_COLORIMETRY_ADOBE_RGB,
HDMI_HDR_EXTENDED_COLORIMETRY_2020_CONST_LUMINOUS, /* BT2020 c_ycc */
HDMI_HDR_EXTENDED_COLORIMETRY_2020_NON_CONST_LUMINOUW
};
/**
* @brief hdr模式。
* 详见HDMI协议2.1。
*
* @since 1.0
*/
enum HdmiHdrMode {
HDMI_HDR_MODE_DISABLE, /* HDR和杜比模式禁用 */
HDMI_HDR_MODE_DOLBY_NORMAL, /* 杜比正常(ycbcr422-12位)模式启用 */
HDMI_HDR_MODE_DOLBY_TUNNELING, /* 杜比隧道(RGB-8bit)模式启用 */
HDMI_HDR_MODE_CEA_861_3, /* HDR标准模式启用(根据<CEA-861-3.2015>) */
HDMI_HDR_MODE_CEA_861_3_AUTHEN, /* HDR授权模式 */
HDMI_HDR_MODE_BUTT
};
/**
* @brief hdr用户模式。
* 详见HDMI协议2.1。
*
* @since 1.0
*/
enum HdmiHdrUserMode {
HDMI_HDR_USERMODE_SDR,
HDMI_HDR_USERMODE_HDR10,
HDMI_HDR_USERMODE_DOLBY,
HDMI_HDR_USERMODE_BUTT
};
/**
* @brief 静态元数据类型。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
enum HdmiStaticMetadataType {
HDMI_DRM_STATIC_METADATA_TYPE_1 = 0, /* 静态元数据类型1 */
HDMI_DRM_STATIC_METADATA_BUTT,
};
/**
* @brief 静态元数据描述符1st。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
struct HdmiStaticMetadataDescriptor1st {
uint16_t displayPrimaries0X; /* display_primaries_x[0], in units of 0.00002 */
uint16_t displayPrimaries0Y; /* display_primaries_y[0], in units of 0.00002 */
uint16_t displayPrimaries1X; /* display_primaries_x[1], in units of 0.00002 */
uint16_t displayPrimaries1Y; /* display_primaries_y[1], in units of 0.00002 */
uint16_t displayPrimaries2X; /* display_primaries_x[2], in units of 0.00002 */
uint16_t displayPrimaries2Y; /* display_primaries_y[2], in units of 0.00002 */
uint16_t whitePointX; /* white_point_x, in units of 0.00002 */
uint16_t whitePointY; /* white_point_y, in units of 0.00002 */
uint16_t maxDisplayMasteringLuminance; /* max_display_mastering_luminance, in units of 1 cd/m^2 */
uint16_t minDisplayMasteringLuminance; /* min_display_mastering_luminance, in units of 0.0001 cd/m^2 */
uint16_t maxContentLightLevel; /* Maximum Content Light Level, in units of 1 cd/m^2 */
uint16_t maxFrameAverageLightLevel; /* Maximum Frame-average Light Level, in units of 1 cd/m^2 */
};
/**
* @brief 定义静态元数据描述符。
* 详见CTA-861-G第6.9节。
*
* @since 1.0
*/
union HdmiStaticMetadataDescriptor {
struct HdmiStaticMetadataDescriptor1st type1;
};
/**
* @brief 定义hdr属性结构。
*
* @since 1.0
*/
struct HdmiHdrAttr {
enum HdmiHdrMode mode;
enum HdmiHdrUserMode userMode;
/* 当模式为HDMI_HDR_mode_CEA_861_3时,以下成员有效 */
enum HdmiEotfType eotfType;
enum HdmiStaticMetadataType metadataType;
union HdmiStaticMetadataDescriptor descriptor;
enum HdmiHdrColormetry colorimetry;
};
/**
* @brief 定义hdmi HPD(热插拔检测)回调信息。
*
* @since 1.0
*/
struct HdmiHpdCallbackInfo {
void *data;
void (*callbackFunc)(void *data, bool hdp);
};
/**
* @brief 打开具有指定总线号的HDMI控制器。
* 在使用HDMI接口之前,您可以获取HDMI控制器的设备句柄。
* 通过调用HdmiOpen,此函数与HdmiClose成对使用。
*
* @param busNum 总线号。
*
* @return 如果操作成功,则返回HDMI控制器的设备句柄DevHandle;否则返回NULL。
*
* @since 1.0
*/
DevHandle HdmiOpen(uint16_t busNum);
/**
* @brief 启动HDMI传输。
* 此函数与HdmiStop成对使用。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiStart(DevHandle handle);
/**
* @brief 停止HDMI传输。
* 此函数与HdmiStart成对使用。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiStop(DevHandle handle);
/**
* @brief HDMI声音图像消隐设置。
* 首先将显示设备置于黑屏静音状态,等待HDMI输出设备开关。接着发送清除AVMute信号,启动显示设备。通过此设置,切换过程中的花屏现象将会被屏蔽掉。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param enable 是否启用avmute。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiAvmuteSet(DevHandle handle, bool enable);
/**
* @brief 设置色深。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param color 要设置的色深,请参见HdmiDeepColor。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiDeepColorSet(DevHandle handle, enum HdmiDeepColor color);
/**
* @brief 获取色深。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param color 指向要获取的色深的指针,请参见HdmiDeepColor。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiDeepColorGet(DevHandle handle, enum HdmiDeepColor *color);
/**
* @brief 设置视频属性。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param attr 指向要设置的视频属性的指针,请参见HdmiVideoAttr。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiSetVideoAttribute(DevHandle handle, struct HdmiVideoAttr *attr);
/**
* @brief 设置音频属性。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param attr 指向要设置的音频属性的指针,请参见HdmiAudioAttr。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiSetAudioAttribute(DevHandle handle, struct HdmiAudioAttr *attr);
/**
* @brief 设置HDR属性。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param attr 指向要设置的hdr属性的指针,请参见HdmiHdrAttr。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiSetHdrAttribute(DevHandle handle, struct HdmiHdrAttr *attr);
/**
* @brief HDMI读取接收器设备的原始EDID数据。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param buffer 指向要读取的数据的指针。
* @param len 要读取的数据的长度。
*
* @return 如果操作成功,返回读取数据的长度;如果操作失败,则返回负值或0。
*
* @since 1.0
*/
int32_t HdmiReadSinkEdid(DevHandle handle, uint8_t *buffer, uint32_t len);
/**
* @brief 注册HPD(热插拔检测)回调函数。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
* @param callback 指向回调信息的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
*
* @since 1.0
*/
int32_t HdmiRegisterHpdCallbackFunc(DevHandle handle, struct HdmiHpdCallbackInfo *callback);
/**
* @brief HDMI注销HPD(热插拔检测)回调函数。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @return 如果操作成功,则返回0;如果操作失败,则返回负值。
* @since 1.0
*/
int32_t HdmiUnregisterHpdCallbackFunc(DevHandle handle);
/**
* @brief 关闭HDMI控制器。
* 使用HDMI接口后,可以通过调用HdmiClose关闭HDMI控制器。此函数与HdmiOpen成对使用。
*
* @param handle 指向HDMI控制器的设备句柄的指针。
*
* @since 1.0
*/
void HdmiClose(DevHandle handle);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* HDMI_IF_H */
/*
* Copyright (c) 2021 Huawei Device 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.
*/
/**
* @addtogroup I3C
* @{
*
* @brief 提供改进的Improved Inter-Integrated Circuit (I3C)接口。
* 该模块允许驱动程序在I3C控制器上执行操作,以访问I3C总线上的设备。
* 包括创建和销毁I3C控制器句柄以及读取和写入数据。
*
* @since 1.0
*/
/**
* @file i3c_if.h
*
* @brief 声明标准I3C接口函数。
*
* @since 1.0
*/
#ifndef I3C_IF_H
#define I3C_IF_H
#include "hdf_platform.h"
#include "i3c_ccc.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
enum TransMode {
/** I2C传输模式 */
I2C_MODE = 0,
/** I3C传输模式 */
I3C_MODE,
/** CCC(通用命令代码)模式 */
CCC_CMD_MODE,
};
enum I3cBusMode {
/** 单数据速率模式 */
I3C_BUS_SDR_MODE = 0,
/** 高数据速率模式 */
I3C_BUS_HDR_MODE,
};
/**
* @brief 定义I3C控制器的配置。
*
* @since 1.0
*/
struct I3cConfig {
/** I3C总线模式 */
enum I3cBusMode busMode;
/** 当前主设备,当控制器是主设备时,其为NULL */
struct I3cDevice *curMaster;
};
/**
* @brief 定义I3C传输、I2C传输或发送CCC(通用命令代码)期间使用的I3C传输消息。
*
* @attention 此结构不限制len指定的数据传输长度,允许的最大长度由特定控制器确定。
* 设备地址addr表示原始设备地址,不需要包含读/写标志位。
* @since 1.0
*/
struct I3cMsg {
/** 目标设备的地址 */
uint16_t addr;
/** 用于存储传输数据的缓冲区地址 */
uint8_t *buf;
/** 传输数据的长度 */
uint16_t len;
/**
* 传输模式标志 | 说明
* ------------| -----------------------
* I2C_FLAG_READ | 读标志
* I2C_FLAG_READ_NO_ACK | 无确认读取标志
* I2C_FLAG_IGNORE_NO_ACK | 忽略无确认标志
* I2C_FLAG_NO_START | 无启动条件标志
* I2C_FLAG_STOP | 停止条件标志
*/
uint16_t flags;
/** 传输模式选择,默认为I2C_MODE */
enum TransMode mode;
/** CCC(通用命令代码)结构,用于CCC_CMD_MODE传输模式 */
struct I3cCccCmd *ccc;
/** I3C错误代码,由驱动程序更新 */
uint16_t err;
};
/**
* @brief 定义I3C IBI(带内中断)的数据。
*
* @attention 生成IBI时,IBI函数中的有效载荷和buf可获得IBI数据。
*
* @since 1.0
*/
struct I3cIbiData {
/** 有效载荷数据长度。IBI有效负载数据的长度。当IBI已生成,读取时请勿修改。 */
uint32_t payload;
/** 数据缓冲区。有效负载数据的指针。 */
uint8_t *buf;
};
enum I3cFlag {
/** 读标志。值1表示读取操作,0表示写入操作。 */
I3C_FLAG_READ = (0x1 << 0),
/** 无ACK读标志。值1表示在读取过程中没有发送ACK信号。 */
I3C_FLAG_READ_NO_ACK = (0x1 << 11),
/** 忽略ACK标志。值1表示忽略非ACK信号。 */
I3C_FLAG_IGNORE_NO_ACK = (0x1 << 12),
/** 无启动条件标志。值1表示消息没有启动条件转移。 */
I3C_FLAG_NO_START = (0x1 << 14),
/** 停止条件标志。值1表示当前传输以停止条件结束。 */
I3C_FLAG_STOP = (0x1 << 15),
};
/**
* @brief IBI(带内中断)回调函数。
* 使用{@link I3cRequestIbi}将其连接到I3C设备。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param addr 重新设置IBI(带内中断)的设备地址。
* @param data IBI的数据结构。
*
* @return 如果操作成功,则返回0;否则返回负值。
* @since 1.0
*/
typedef int32_t (*I3cIbiFunc)(DevHandle handle, uint16_t addr, struct I3cIbiData data);
/**
* @brief 获取I3C控制器的句柄。
* 在访问I3C总线之前,必须调用此函数。
*
* @param number I3C控制器ID。
*
* @return 如果操作成功,则返回指向I3C控制器的DevHandle的指针;否则返回NULL。
*
* @since 1.0
*/
DevHandle I3cOpen(int16_t number);
/**
* @brief 释放I3C控制器的句柄。
* 如果不再需要访问I3C控制器,则应调用此函数关闭其句柄,以便释放未使用的内存资源。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
*
* @since 1.0
*/
void I3cClose(DevHandle handle);
/**
* @brief 启动到I3C设备或兼容的I2C设备的传输,或者向支持的I3C设备发送CCC(通用命令代码)。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param msg 指向I3C传输消息结构数组的指针。
* @param count 消息结构数组的长度。
* @param mode 传输模式。
*
* @return 如果操作成功,返回传输的消息结构数;
* @see I3cMsg
* @attention 此结构不限制len指定的数据传输长度。 特定的 I3C 控制器决定了允许的最大长度。 设备地址addr表示原始设备地址,不需要包含读/写标志位。
*
* @since 1.0
*/
int32_t I3cTransfer(DevHandle handle, struct I3cMsg *msg, int16_t count, enum TransMode mode);
/**
* @brief 重新设置受支持的I3C设备的IBI(带内中断)。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param addr 重新设置IBI(带内中断)的设备地址。
* @param func IBI回调函数。
* @param payload 有效负载数据的长度,以字节为单位。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cRequestIbi(DevHandle handle, uint16_t addr, I3cIbiFunc func, uint32_t payload);
/**
* @brief 释放{@link I3cRequestIbi}重新设置的IBI(带内中断)。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param addr 要释放IBI的设备的地址。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cFreeIbi(DevHandle handle, uint16_t addr);
/**
* @brief 设置I3C控制器的配置。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param config 要设置的配置结构的指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cSetConfig(DevHandle handle, struct I3cConfig *config);
/**
* @brief 获取I3C控制器的配置。
*
* @param handle 指向通过{@link I3cOpen}获得的I3C控制器句柄的指针。
* @param config 用于存储配置的结构体。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t I3cGetConfig(DevHandle handle, struct I3cConfig *config);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* I3C_IF_H */
/** @} */
/*
* Copyright (c) 2021 Huawei Device 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.
*/
/**
* @addtogroup MIPI CSI
* @{
*
* @brief 定义用于外设接收端驱动程序开发的标准MIPI CSI API。
* 此MIPI CSI模块抽象了不同系统平台的MIPI CSI功能,以提供稳定的API。
* 用于外设接收端驱动程序开发。您可以使用此模块获取/释放MIPI CSI设备句柄。
*
* @since 1.0
*/
/**
* @file mipi_csi_if.h
*
* @brief 声明用于显示驱动程序开发的标准MIPI CSI API。
*
*
*
* @since 1.0
*/
#ifndef MIPI_CSI_IF_H
#define MIPI_CSI_IF_H
#include "hdf_platform.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
/**
* @brief MIPI RX的MIPI设备支持的最大通道数。
*
* @since 1.0
*/
#define MIPI_LANE_NUM 4
/**
* @brief Mipi Rx的LVDS设备支持的最大通道数。
*
* @since 1.0
*/
#define LVDS_LANE_NUM 4
/**
* @brief 定义支持的最大虚拟通道数。
*
* @since 1.0
*/
#define WDR_VC_NUM 4
/**
* @brief 为LVDS的每个虚拟通道定义同步代码的数量。
*
* @since 1.0
*/
#define SYNC_CODE_NUM 4
/**
* @brief 最多3组扩展数据类型。
*
* @since 1.0
*/
#define MAX_EXT_DATA_TYPE_NUM 3
/**
* @brief Mipi-Rx的通道分布。
*
* @since 1.0
*/
typedef enum {
LANE_DIVIDE_MODE_0 = 0,
LANE_DIVIDE_MODE_1 = 1,
LANE_DIVIDE_MODE_BUTT
} LaneDivideMode;
/**
* @brief MIPI接收输入接口类型。
*
* @since 1.0
*/
typedef enum {
/** mipi */
INPUT_MODE_MIPI = 0x0,
/** SUB_LVDS */
INPUT_MODE_SUBLVDS = 0x1,
/** LVDS */
INPUT_MODE_LVDS = 0x2,
/* HISPI */
INPUT_MODE_HISPI = 0x3,
/** CMOS */
INPUT_MODE_CMOS = 0x4,
/** BT601 */
INPUT_MODE_BT601 = 0x5,
/** BT656 */
INPUT_MODE_BT656 = 0x6,
/** BT1120 */
INPUT_MODE_BT1120 = 0x7,
/** MIPI Bypass */
INPUT_MODE_BYPASS = 0x8,
INPUT_MODE_BUTT
} InputMode;
/**
* @brief MIPI接收速率。
*
* @since 1.0
*/
typedef enum {
/** output 1 pixel per clock */
MIPI_DATA_RATE_X1 = 0,
/** output 2 pixel per clock */
MIPI_DATA_RATE_X2 = 1,
MIPI_DATA_RATE_BUTT
} MipiDataRate;
/**
* @brief Mipi图像区域。
*
* @since 1.0
*/
typedef struct {
int x;
int y;
unsigned int width;
unsigned int height;
} ImgRect;
/**
* @brief 传输的数据类型。
*
* @since 1.0
*/
typedef enum {
DATA_TYPE_RAW_8BIT = 0,
DATA_TYPE_RAW_10BIT,
DATA_TYPE_RAW_12BIT,
DATA_TYPE_RAW_14BIT,
DATA_TYPE_RAW_16BIT,
DATA_TYPE_YUV420_8BIT_NORMAL,
DATA_TYPE_YUV420_8BIT_LEGACY,
DATA_TYPE_YUV422_8BIT,
/** YUV422 8位转换用户定义16位原始数据 */
DATA_TYPE_YUV422_PACKED,
DATA_TYPE_BUTT
} DataType;
/**
* @brief 定义YUV和原始数据格式以及位深度。
*
* @since 1.0
*/
typedef struct {
uint8_t devno;
unsigned int num;
unsigned int extDataBitWidth[MAX_EXT_DATA_TYPE_NUM];
unsigned int extDataType[MAX_EXT_DATA_TYPE_NUM];
} ExtDataType;
/**
* @brief MIPI D-PHY WDR模式定义。
*
* @since 1.0
*/
typedef enum {
HI_MIPI_WDR_MODE_NONE = 0x0,
/** Virtual Channel */
HI_MIPI_WDR_MODE_VC = 0x1,
/** Data Type */
HI_MIPI_WDR_MODE_DT = 0x2,
/** DOL Mode */
HI_MIPI_WDR_MODE_DOL = 0x3,
HI_MIPI_WDR_MODE_BUTT
} MipiWdrMode;
/**
* @brief Mipi设备属性。
*
* @since 1.0
*/
typedef struct {
/** 数据类型:8/10/12/14/16位 */
DataType inputDataType;
/** MIPI WDR模式定义 */
MipiWdrMode wdrMode;
/** 通道id: -1 - 禁用 */
short laneId[MIPI_LANE_NUM];
union {
/** 由HI_MIPI_WDR_MODE_DT使用 */
short dataType[WDR_VC_NUM];
};
} MipiDevAttr;
/**
* @brief LVDS WDR模式定义。
*
* @since 1.0
*/
typedef enum {
HI_WDR_MODE_NONE = 0x0,
HI_WDR_MODE_2F = 0x1,
HI_WDR_MODE_3F = 0x2,
HI_WDR_MODE_4F = 0x3,
HI_WDR_MODE_DOL_2F = 0x4,
HI_WDR_MODE_DOL_3F = 0x5,
HI_WDR_MODE_DOL_4F = 0x6,
HI_WDR_MODE_BUTT
} WdrMode;
/**
* @brief LVDS同步模式。
*
* @since 1.0
*/
typedef enum {
/** 传感器SOL、EOL、SOF、EOF */
LVDS_SYNC_MODE_SOF = 0,
/** SAV, EAV */
LVDS_SYNC_MODE_SAV,
LVDS_SYNC_MODE_BUTT
} LvdsSyncMode;
/**
* @brief LVDS 列同步类型。
*
* @since 1.0
*/
typedef enum {
LVDS_VSYNC_NORMAL = 0x00,
LVDS_VSYNC_SHARE = 0x01,
LVDS_VSYNC_HCONNECT = 0x02,
LVDS_VSYNC_BUTT
} LvdsVsyncType;
/**
* @brief LVDS-Vsync列同步参数。
*
* @since 1.0
*/
typedef struct {
LvdsVsyncType syncType;
/* 当 sync_type 为 LVDS_VSYNC_HCONNECT 时,需要配置 hblank1 和 hblank2,表示 Hconnect 的消隐区长度 */
unsigned short hblank1;
unsigned short hblank2;
} LvdsVsyncAttr;
/**
* @brief 帧ID类型。
*
* @since 1.0
*/
typedef enum {
LVDS_FID_NONE = 0x00,
/** SAV 4th中的帧标识id */
LVDS_FID_IN_SAV = 0x01,
/** 第一个数据中的帧标识id */
LVDS_FID_IN_DATA = 0x02,
LVDS_FID_BUTT
} LvdsFidType;
/**
* @brief 帧ID配置信息。
*
* @since 1.0
*/
typedef struct {
LvdsFidType fidType;
/** 索尼DOL有帧信息线,在DOL H连接模式下,
应将此标志配置为false以禁用输出帧信息行。 */
unsigned char outputFil;
} LvdsFidAttr;
/**
* @brief 位大小端模式。
*
* @since 1.0
*/
typedef enum {
LVDS_ENDIAN_LITTLE = 0x0,
LVDS_ENDIAN_BIG = 0x1,
LVDS_ENDIAN_BUTT
} LvdsBitEndian;
/**
* @brief LVDS/SUBSLVDS/HiSPi设备属性。
*
* @since 1.0
*/
typedef struct {
/** 数据类型:8/10/12/14位 */
DataType inputDataType;
/** 波分复用模式 */
WdrMode wdrMode;
/** 同步模式:SOF,SAV */
LvdsSyncMode syncMode;
/** 正常、共享、连接 */
LvdsVsyncAttr vsyncAttr;
/** 帧识别码 */
LvdsFidAttr fidAttr;
/** 数据端:小/大 */
LvdsBitEndian dataEndian;
/** 同步代码endian:小/大 */
LvdsBitEndian syncCodeEndian;
/** 通道id: -1 - 禁用 */
short laneId[LVDS_LANE_NUM];
/** 每个vc有4个参数,syncCode[i]:
同步模式是SYNC_MODE_SOF:SOF、EOF、SOL、EOL
同步模式是SYNC_MODE_SAV:无效SAV、无效eav、有效SAV、有效eav */
unsigned short syncCode[LVDS_LANE_NUM][WDR_VC_NUM][SYNC_CODE_NUM];
} LvdsDevAttr;
/**
* @brief 组合设备的属性。
* 组合设备属性,由于 MIPI Rx 能够对接 CSI-2、LVDS、HiSPi 等时序,所以将 MIPI Rx 称为组合设备。
*
* @since 1.0
*/
typedef struct {
/** 设备号 */
uint8_t devno;
/** 输入模式:MIPI/LVDS/SUBSLVDS/HISPI/DC */
InputMode inputMode;
MipiDataRate dataRate;
/** MIPI Rx设备裁剪区域(与原始传感器输入图像大小相对应) */
ImgRect imgRect;
union {
MipiDevAttr mipiAttr;
LvdsDevAttr lvdsAttr;
};
} ComboDevAttr;
/**
* @brief 共模电压模式。
*
* @since 1.0
*/
typedef enum {
PHY_CMV_GE1200MV = 0x00,
PHY_CMV_LT1200MV = 0x01,
PHY_CMV_BUTT
} PhyCmvMode;
/**
* @brief 获取具有指定通道ID的MIPI CSI设备句柄。
*
* @param id 表示 MIPI CSI通道id。
*
* @return 如果操作成功,则返回MIPI CSI设备句柄;否则返回NULL。
*
* @since 1.0
*/
DevHandle MipiCsiOpen(uint8_t id);
/**
* @brief 释放MIPI CSI设备句柄。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
*
* @since 1.0
*/
void MipiCsiClose(DevHandle handle);
/**
* @brief 将Mipi、CMOS或LVDS摄像机的参数设置到控制器。
* 参数包括工作模式、图像面积、图像深度、数据速率和物理通道。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param pAttr 指向属性的指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
/**
* @brief 设置共模电压模式。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param devno 总共有2个设备编号,指向0或1。
* @param cmvMode 共模电压模式参数。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode);
/**
* @brief 复位传感器。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsResetSource 传感器的复位信号线号在软件中称为传感器的复位源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource);
/**
* @brief 撤销复位传感器。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsResetSource 传感器的复位信号线号在软件中称为传感器的复位源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource);
/**
* @brief 复位 MIPI RX。
* 不同的s32WorkingViNum有不同的enSnsType。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI Rx或者SLVS 设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev);
/**
* @brief 未设置的MIPI RX.
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI Rx或者SLVS 设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev);
/**
* @brief 设置Mipi Rx的通道分布。
* 根据硬件连接形式选择具体模式。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param laneDivideMode 通道划分模式参数。
*
* @since 1.0
*/
int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode);
/**
* @brief 使能mipi的时钟。
* 根据上层函数电泳传递的enSnsType参数决定是用 MIPI 还是LVDS。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI接收或LVDS设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev);
/**
* @brief 关闭Mipi的时钟。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param comboDev MIPI接收或LVDS设备类型。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev);
/**
* @brief 启用Mipi上的传感器时钟。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsClkSource 传感器的时钟信号线号,在软件中称为传感器的时钟源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource);
/**
* @brief 关闭传感器时钟。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param snsClkSource 传感器的时钟信号线号,在软件中称为传感器的时钟源。
* sns是传感器的缩写。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource);
/**
* @brief 设置YUV和原始数据格式以及位深度。
*
* @param handle 通过{@link MipiCsiOpen}获得的MIPI CSI设备句柄。
* @param dataType 指向图像数据格式的指针。
*
* @return 如果操作成功,则返回0;否则返回负值。
*
* @since 1.0
*/
int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* MIPI_CSI_IF_H */
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
- [SPI](driver-platform-spi-develop.md) - [SPI](driver-platform-spi-develop.md)
- [UART](driver-platform-uart-develop.md) - [UART](driver-platform-uart-develop.md)
- [WatchDog](driver-platform-watchdog-develop.md) - [WatchDog](driver-platform-watchdog-develop.md)
- [MIPI_CSI](driver-platform-mipicsi-develop.md)
- [平台驱动使用](driver-platform.md) - [平台驱动使用](driver-platform.md)
- [GPIO](driver-platform-gpio-des.md) - [GPIO](driver-platform-gpio-des.md)
- [I2C](driver-platform-i2c-des.md) - [I2C](driver-platform-i2c-des.md)
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
- [WATCHDOG](driver-platform-watchdog-des.md) - [WATCHDOG](driver-platform-watchdog-des.md)
- [MIPI DSI](driver-platform-mipidsi-des.md) - [MIPI DSI](driver-platform-mipidsi-des.md)
- [PWM](driver-platform-pwm-des.md) - [PWM](driver-platform-pwm-des.md)
- [MIPI_CSI](driver-platform-mipicsi-des.md)
- [外设驱动使用](driver-peripherals.md) - [外设驱动使用](driver-peripherals.md)
- [LCD](driver-peripherals-lcd-des.md) - [LCD](driver-peripherals-lcd-des.md)
- [TOUCHSCREEN](driver-peripherals-touch-des.md) - [TOUCHSCREEN](driver-peripherals-touch-des.md)
......
# MIPI CSI<a name="title_MIPI_CSIDes"></a>
- [概述](#section1_MIPI_CSIDes)
- [ComboDevAttr结构体](#section1.1_MIPI_CSIDes)
- [ExtDataType结构体](#section1.2_MIPI_CSIDes)
- [接口说明](#section1.3_MIPI_CSIDes)
- [使用指导](#section2_MIPI_CSIDes)
- [使用流程](#section2.1_MIPI_CSIDes)
- [获取MIPI-CSI控制器操作句柄](#section2.2_MIPI_CSIDes)
- [MIPI-CSI相应配置](#section2.3_MIPI_CSIDes)
- [复位/撤销复位sensor](#section2.4_MIPI_CSIDes)
- [复位/撤销复位MIPI RX](#section2.5_MIPI_CSIDes)
- [使能/关闭MIPI的时钟](#section2.6_MIPI_CSIDes)
- [使能/关闭MIPI上的sensor时钟](#section2.7_MIPI_CSIDes)
- [释放MIPI-CSI控制器操作句柄](#section2.8_MIPI_CSIDes)
- [使用实例](#section3_MIPI_CSIDes)
## 概述<a name="section1_MIPI_CSIDes"></a>
- CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。CSI-2是MIPI CSI第二版,主要由应用层、协议层、物理层组成,最大支持4通道数据传输、单线传输速度高达1Gb/s。
- 物理层支持HS(High Speed)和LP(Low Power)两种工作模式。HS模式下采用低压差分信号,功耗较大,但数据传输速率可以很高(数据速率为80M~1Gbps);LP模式下采用单端信号,数据速率很低(<10Mbps),但是相应的功耗也很低。两种模式的结合保证了MIPI总线在需要传输大量数据(如图像)时可以高速传输,而在不需要传输大数据量时又能够减少功耗。
- 图1显示了简化的CSI接口。D-PHY采用1对源同步的差分时钟和1~4对差分数据线来进行数据传输。数据传输采用DDR方式,即在时钟的上下边沿都有数据传输。
**图 1** CSI发送、接收接口<a name="fig1_MIPI_CSIDes"></a>
![](figures/CSI发送-接收接口.png)
### ComboDevAttr结构体<a name="section1.1_MIPI_CSIDes"></a>
**表** **1** ComboDevAttr结构体介绍
<a name="table1_MIPI_CSIDes"></a>
| 名称 | 描述 |
| --------- | ----------------------------------------------------- |
| devno | 设备号 |
| inputMode | 输入模式:MIPI/LVDS/SUBSLVDS/HISPI/DC |
| dataRate | Mipi Rx,SLVS输入速率 |
| imgRect | MIPI Rx设备裁剪区域(与原始传感器输入图像大小相对应) |
| MIPIAttr | Mipi设备属性 |
| lvdsAttr | LVDS/SubLVDS/HiSPi设备属性 |
### ExtDataType结构体<a name="section1.2_MIPI_CSIDes"></a>
**表** **2** ExtDataType结构体介绍
<a name="table2_MIPI_CSIDes"></a>
| 名称 | 描述 |
| --------------- | ------------------------------- |
| devno | 设备号 |
| num | sensor号 |
| extDataBitWidth | 图片的位深 |
| extDataType | 定义YUV和原始数据格式以及位深度 |
### 接口说明<a name="section1.3_MIPI_CSIDes"></a>
**表 3** MIPI-CSI API接口功能介绍
<a name="table3_MIPI_CSIDes"></a>
<table border="0" cellpadding="0" cellspacing="0" width="700" style="border-collapse:
collapse;table-layout:fixed;width:855pt">
<colgroup><col class="xl66" width="200" style="mso-width-source:userset;mso-width-alt:7072;
width:166pt">
<col width="250" style="mso-width-source:userset;mso-width-alt:8800;width:206pt">
<col class="xl71" width="300" style="mso-width-source:userset;mso-width-alt:9792;
width:230pt">
</colgroup><tbody><tr class="xl65" height="19" style="height:14.25pt">
<td height="19" class="xl65" width="221" style="height:14.25pt;width:166pt">功能分类</td>
<td class="xl65" width="275" style="width:206pt">接口名</td>
<td class="xl69" width="306" style="width:230pt">描述</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td rowspan="2" height="38" class="xl67" style="height:28.5pt">获取/释放MIPI-CSI控制器操作句柄</td>
<td class="xl68">MipiCsiOpen</td>
<td class="xl70" width="306" style="width:230pt">获取MIPI-CSI控制器操作句柄</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td height="19" class="xl68" style="height:14.25pt">MipiCsiClose</td>
<td class="xl70" width="306" style="width:230pt">释放MIPI-CSI控制器操作句柄</td>
</tr>
<tr class="xl68" height="114" style="height:85.5pt">
<td rowspan="4" height="228" class="xl67" style="height:171.0pt">MIPI-CSI相应配置</td>
<td class="xl68">MipiCsiSetComboDevAttr</td>
<td class="xl70" width="306" style="width:230pt">设置MIPI,CMOS 或者
LVDS相机的参数给控制器,参数包括工作模式,图像区域,图像深度,数据速率和物理通道等</td>
</tr>
<tr class="xl68" height="38" style="height:28.5pt">
<td height="38" class="xl68" style="height:28.5pt">MipiCsiSetExtDataType(可选)</td>
<td class="xl70" width="306" style="width:230pt">设置YUV和RAW数据格式和位深</td>
</tr>
<tr class="xl68" height="57" style="height:42.75pt">
<td height="57" class="xl68" style="height:42.75pt">MipiCsiSetHsMode</td>
<td class="xl70" width="306" style="width:230pt">设置MIPI RX的 Lane
分布。根据硬件连接的形式选择具体的mode</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td height="19" class="xl68" style="height:14.25pt">MipiCsiSetPhyCmvmode</td>
<td class="xl70" width="306" style="width:230pt">设置共模电压模式</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td rowspan="2" height="38" class="xl67" style="height:28.5pt">复位/撤销复位 sensor</td>
<td class="xl68">MipiCsiResetSensor</td>
<td class="xl70" width="306" style="width:230pt">复位 sensor</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td height="19" class="xl68" style="height:14.25pt">MipiCsiUnresetSensor</td>
<td class="xl70" width="306" style="width:230pt">撤销复位 sensor</td>
</tr>
<tr class="xl68" height="57" style="height:42.75pt">
<td rowspan="2" height="76" class="xl67" style="height:57.0pt">复位/撤销复位 MIPI RX</td>
<td class="xl68">MipiCsiResetRx</td>
<td class="xl70" width="306" style="width:230pt">复位 MIPI
RX。不同的s32WorkingViNum有不同的enSnsType</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td height="19" class="xl68" style="height:14.25pt">MipiCsiUnresetRx</td>
<td class="xl70" width="306" style="width:230pt">撤销复位 MIPI RX</td>
</tr>
<tr class="xl68" height="76" style="height:57.0pt">
<td rowspan="2" height="95" class="xl67" style="height:71.25pt">使能/关闭MIPI的时钟</td>
<td class="xl68">MipiCsiEnableClock</td>
<td class="xl70" width="306" style="width:230pt">使能MIPI的时钟。根据上层函数电泳传递的enSnsType参数决定是用
MIPI 还是LVDS</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td height="19" class="xl68" style="height:14.25pt">MipiCsiDisableClock</td>
<td class="xl70" width="306" style="width:230pt">关闭MIPI设备的时钟</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td rowspan="2" height="38" class="xl67" style="height:28.5pt">使能/禁用MIPI上的sensor时钟</td>
<td class="xl68">MipiCsiEnableSensorClock</td>
<td class="xl70" width="306" style="width:230pt">使能MIPI上的sensor时钟</td>
</tr>
<tr class="xl68" height="19" style="height:14.25pt">
<td height="19" class="xl68" style="height:14.25pt">MipiCsiDisableSensorClock</td>
<td class="xl70" width="306" style="width:230pt">关闭 sensor 的时钟</td>
</tr>
<!--[if supportMisalignedColumns]-->
<tr height="0" style="display:none">
<td width="221" style="width:166pt"></td>
<td width="275" style="width:206pt"></td>
<td width="306" style="width:230pt"></td>
</tr>
<!--[endif]-->
</tbody></table>
## 使用指导<a name="section2_MIPI_CSIDes"></a>
### 使用流程<a name="section2.1_MIPI_CSIDes"></a>
使用MIPI-CSI的一般流程如[图2](#fig99821771782)所示。
**图 2** MIPI-CSI使用流程图<a name="fig2_MIPI_CSIDes"></a>
![](figures/MIPI-CSI使用流程图.png)
### 获取MIPI-CSI控制器操作句柄<a name="section2.2_MIPI_CSIDes"></a>
在进行MIPI-CSI进行通信前,首先要调用MipiCsiOpen获取控制器操作句柄,该函数会返回指定通道ID的控制器操作句柄。
```c
DevHandle MipiCsiOpen(uint8_t id);
```
**表 4** MipiCsiOpen的参数和返回值描述
<a name="table4_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | ----------------------------------------------- |
| id | MIPI CSI通道ID |
| **返回值** | **返回值描述** |
| NULL | 获取失败 |
| 设备句柄 | 获取到指令通道的控制器操作句柄,类型为DevHandle |
假设系统中的MIPI-CSI通道为0,获取该通道控制器操作句柄的示例如下:
```c
DevHandle MipiCsiHandle = NULL; /* 设备句柄 */
id = 0; /* MiPi-Csi通道ID */
/* 获取控制器操作句柄 */
MipiCsiHandle = MipiCsiOpen(id);
if (MipiCsiHandle == NULL) {
HDF_LOGE("MipiCsiOpen: failed\n");
return;
}
```
### MIPI-CSI相应配置<a name="section2.3_MIPI_CSIDes"></a>
- 写入MIPI-CSI配置
```c
int32_t MipiCsiSetComboDevAttr(DevHandle handle, ComboDevAttr *pAttr);
```
**表 5** MipiCsiSetComboDevAttr的参数和返回值描述
<a name="table5_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | -------------------------- |
| handle | 控制器操作句柄 |
| pAttr | MIPI-CSI相应配置结构体指针 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret;
struct ComboDevAttr attr;
/* 当前配置如下 */
(void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
attr.devno = 0; /* 设备0 */
attr.inputMode = INPUT_MODE_MIPI; /* 输入模式为MIPI */
attr.dataRate = MIPI_DATA_RATE_X1; /* 每时钟输出1像素 */
attr.imgRect.x = 0; /* 0: 图像传感器左上位置 */
attr.imgRect.y = 0; /* 0: 图像传感器右上位置 */
attr.imgRect.width = 2592; /* 2592: 图像传感器宽度大小 */
attr.imgRect.height = 1944; /* 1944: 图像传感器高度尺寸 */
/* 写入配置数据 */
ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 设置YUV和RAW数据格式和位深
```c
int32_t MipiCsiSetExtDataType(DevHandle handle, ExtDataType* dataType);
```
**表 6** MipiCsiSetExtDataType的参数和返回值描述
<a name="table6_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | ------------------------------- |
| handle | 控制器操作句柄 |
| dataType | 定义YUV和原始数据格式以及位深度 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret;
struct ExtDataType dataType;
/* 配置YUV和RAW数据格式和位深参数 */
dataType.devno = 0; /* 设备0 */
dataType.num = 0; /* sensor 0 */
dataType.extDataBitWidth[0] = 12; /* 位深数组元素0 */
dataType.extDataBitWidth[1] = 12; /* 位深数组元素1 */
dataType.extDataBitWidth[2] = 12; /* 位深数组元素2 */
dataType.extDataType[0] = 0x39; /* 定义YUV和原始数据格式以及位深度元素0 */
dataType.extDataType[1] = 0x39; /* 定义YUV和原始数据格式以及位深度元素1 */
dataType.extDataType[2] = 0x39; /* 定义YUV和原始数据格式以及位深度元素2 */
/* 设置YUV和RAW数据格式和位深 */
ret = MipiCsiSetExtDataType(MipiCsiHandle, &dataType);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetExtDataType fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 设置MIPI RX的 Lane分布
```c
int32_t MipiCsiSetHsMode(DevHandle handle, LaneDivideMode laneDivideMode);
```
**表 7** MipiCsiSetHsMode的参数和返回值描述
<a name="table7_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| -------------- | -------------- |
| handle | 控制器操作句柄 |
| laneDivideMode | lane模式参数 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret;
enum LaneDivideMode mode;
/* lane模式参数为0 */
mode = LANE_DIVIDE_MODE_0;
/* 设置MIPI RX的 Lane分布 */
ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 设置共模电压模式
```c
int32_t MipiCsiSetPhyCmvmode(DevHandle handle, uint8_t devno, PhyCmvMode cmvMode);
```
**表 8** MipiCsiSetPhyCmvmode的参数和返回值描述
<a name="table8_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | ---------------- |
| handle | 控制器操作句柄 |
| cmvMode | 共模电压模式参数 |
| devno | 设备编号 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret;
enum PhyCmvMode mode;
uint8_t devno;
/* 共模电压模式参数为0 */
mode = PHY_CMV_GE1200MV;
/* 设备编号为0 */
devno = 0;
/* 设置共模电压模式 */
ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret);
return -1;
}
```
### 复位/撤销复位sensor<a name="section2.4_MIPI_CSIDes"></a>
- 复位sensor
```c
int32_t MipiCsiResetSensor(DevHandle handle, uint8_t snsResetSource);
```
**表 9** MipiCsiResetSensor的参数和返回值描述
<a name="table9_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| -------------- | ------------------------------------------------ |
| handle | 控制器操作句柄 |
| snsResetSource | 传感器的复位信号线号,在软件中称为传感器的复位源 |
| **返回值** | **返回值描述** |
| 0 | 复位成功 |
| 负数 | 复位失败 |
```c
int32_t ret;
uint8_t snsResetSource;
/* 传感器复位信号线号为0 */
snsResetSource = 0;
/* 复位sensor */
ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 撤销复位sensor
```c
int32_t MipiCsiUnresetSensor(DevHandle handle, uint8_t snsResetSource);
```
**表 10** MipiCsiUnresetSensor的参数和返回值描述
<a name="table10_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| -------------- | ------------------------------------------------ |
| handle | 控制器操作句柄 |
| snsResetSource | 传感器的复位信号线号,在软件中称为传感器的复位源 |
| **返回值** | **返回值描述** |
| 0 | 撤销复位成功 |
| 负数 | 撤销复位失败 |
```c
int32_t ret;
uint8_t snsResetSource;
/* 传感器撤销复位信号线号为0 */
snsResetSource = 0;
/* 撤销复位sensor */
ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret);
return -1;
}
```
### 复位/撤销复位MIPI RX<a name="section2.5_MIPI_CSIDes"></a>
- 复位MIPI RX
```c
int32_t MipiCsiResetRx(DevHandle handle, uint8_t comboDev);
```
**表 11** MipiCsiResetRx的参数和返回值描述
<a name="table11_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | --------------------- |
| handle | 控制器操作句柄 |
| comboDev | MIPI RX或LVDS通路序号 |
| **返回值** | **返回值描述** |
| 0 | 复位成功 |
| 负数 | 复位失败 |
```c
int32_t ret;
uint8_t comboDev;
/* 通路序号为0 */
comboDev = 0;
/* 复位MIPI RX */
ret = MipiCsiResetRx(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 撤销复位MIPI RX
```c
int32_t MipiCsiUnresetRx(DevHandle handle, uint8_t comboDev);
```
**表 12** MipiCsiUnresetRx的参数和返回值描述
<a name="table12_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | --------------------- |
| handle | 控制器操作句柄 |
| comboDev | MIPI RX或LVDS通路序号 |
| **返回值** | **返回值描述** |
| 0 | 撤销复位成功 |
| 负数 | 撤销复位失败 |
```c
int32_t ret;
uint8_t comboDev;
/* 通路序号为0 */
comboDev = 0;
/* 撤销复位MIPI RX */
ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret);
return -1;
}
```
### 使能/关闭MIPI的时钟<a name="section2.6_MIPI_CSIDes"></a>
- 使能MIPI的时钟
```c
int32_t MipiCsiEnableClock(DevHandle handle, uint8_t comboDev);
```
**表 13** MipiCsiEnableClock的参数和返回值描述
<a name="table13_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | -------------- |
| handle | 控制器操作句柄 |
| comboDev | 通路序号 |
| **返回值** | **返回值描述** |
| 0 | 使能成功 |
| 负数 | 使能失败 |
```c
int32_t ret;
uint8_t comboDev;
/* 通路序号为0 */
comboDev = 0;
/* 使能MIPI的时钟 */
ret = MipiCsiEnableClock(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 关闭MIPI的时钟
```c
int32_t MipiCsiDisableClock(DevHandle handle, uint8_t comboDev);
```
**表 14** MipiCsiDisableClock的参数和返回值描述
<a name="table14_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ---------- | -------------- |
| handle | 控制器操作句柄 |
| comboDev | 通路序号 |
| **返回值** | **返回值描述** |
| 0 | 关闭成功 |
| 负数 | 关闭失败 |
```c
int32_t ret;
uint8_t comboDev;
/* 通路序号为0 */
comboDev = 0;
/* 关闭MIPI的时钟 */
ret = MipiCsiDisableClock(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret);
return -1;
}
```
### 使能/关闭MIPI上的sensor时钟<a name="section2.7_MIPI_CSIDes"></a>
- 使能MIPI上的sensor时钟
```c
int32_t MipiCsiEnableSensorClock(DevHandle handle, uint8_t snsClkSource);
```
**表 15** MipiCsiEnableSensorClock的参数和返回值描述
<a name="table15_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ------------ | ------------------------------------------------ |
| handle | 控制器操作句柄 |
| snsClkSource | 传感器的时钟信号线号,在软件中称为传感器的时钟源 |
| **返回值** | **返回值描述** |
| 0 | 使能成功 |
| 负数 | 使能失败 |
```c
int32_t ret;
uint8_t snsClkSource;
/* 传感器的时钟信号线号为0 */
snsClkSource = 0;
/* 使能MIPI上的sensor时钟 */
ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret);
return -1;
}
```
- 关闭MIPI上的sensor时钟
```c
int32_t MipiCsiDisableSensorClock(DevHandle handle, uint8_t snsClkSource);
```
**表 16** MipiCsiDisableSensorClock的参数和返回值描述
<a name="table16_MIPI_CSIDes"></a>
| 参数 | 参数描述 |
| ------------ | ------------------------------------------------ |
| handle | 控制器操作句柄 |
| snsClkSource | 传感器的时钟信号线号,在软件中称为传感器的时钟源 |
| **返回值** | **返回值描述** |
| 0 | 关闭成功 |
| 负数 | 关闭失败 |
```c
int32_t ret;
uint8_t snsClkSource;
/* 传感器的时钟信号线号为0 */
snsClkSource = 0;
/* 关闭MIPI上的sensor时钟 */
ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret);
return -1;
}
```
### 释放MIPI-CSI控制器操作句柄<a name="section2.8_MIPI_CSIDes"></a>
MIPI-CSI使用完成之后,需要释放控制器操作句柄,释放句柄的函数如下所示:
```c
void MipiCsiClose(DevHandle handle);
```
该函数会释放掉由MipiCsiOpen申请的资源。
**表 17** MipiCsiClose的参数和返回值描述
<a name="table17_MIPI_CSIDes"></a>
<table><thead align="left"><tr id="row1525793312"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p115402031153111"><a name="p115402031153111"></a><a name="p115402031153111"></a>参数</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p65406313319"><a name="p65406313319"></a><a name="p65406313319"></a>参数描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row1926109193116"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p105419317318"><a name="p105419317318"></a><a name="p105419317318"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p132442255912"><a name="p132442255912"></a><a name="p132442255912"></a>MIPI-CSI控制器操作句柄</p>
</td>
</tr>
</tbody>
</table>
```c
MipiCsiClose(MIPIHandle); /* 释放掉MIPI-CSI控制器操作句柄 */
```
## 使用实例<a name="section3_MIPI_CSIDes"></a>
MIPI-CSI完整的使用示例如下所示:
```c
#include "hdf.h"
#include "MIPI_csi_if.h"
void PalMipiCsiTestSample(void)
{
uint8_t id;
int32_t ret;
uint8_t comboDev;
uint8_t snsClkSource;
uint8_t devno;
enum LaneDivideMode mode;
enum PhyCmvMode mode;
struct ComboDevAttr attr;
struct ExtDataType dataType;
DevHandle MipiCsiHandle = NULL;
/* 控制器ID号 */
id = 0;
/* 获取控制器操作句柄 */
MipiCsiHandle = MipiCsiOpen(id);
if (MipiCsiHandle == NULL) {
HDF_LOGE("MipiCsiOpen: failed!\n");
return;
}
/* lane模式参数为0 */
mode = LANE_DIVIDE_MODE_0;
/* 设置MIPI RX的 Lane分布 */
ret = MipiCsiSetHsMode(MipiCsiHandle, mode);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetHsMode fail! ret=%d\n", __func__, ret);
return;
}
/* 通路序号为0 */
comboDev = 0;
/* 使能MIPI的时钟 */
ret = MipiCsiEnableClock(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiEnableClock fail! ret=%d\n", __func__, ret);
return;
}
/* 复位MIPI RX */
ret = MipiCsiResetRx(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiResetRx fail! ret=%d\n", __func__, ret);
return;
}
/* 传感器的时钟信号线号为0 */
snsClkSource = 0;
/* 使能MIPI上的sensor时钟 */
ret = MipiCsiEnableSensorClock(MipiCsiHandle, snsClkSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiEnableSensorClock fail! ret=%d\n", __func__, ret);
return;
}
/* 复位sensor */
ret = MipiCsiResetSensor(MipiCsiHandle, snsResetSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiResetSensor fail! ret=%d\n", __func__, ret);
return;
}
/* MIPI参数配置如下 */
(void)memset_s(&attr, sizeof(ComboDevAttr), 0, sizeof(ComboDevAttr));
attr.devno = 0; /* 设备0 */
attr.inputMode = INPUT_MODE_MIPI; /* 输入模式为MIPI */
attr.dataRate = MIPI_DATA_RATE_X1; /* 每时钟输出1像素 */
attr.imgRect.x = 0; /* 0: 图像传感器左上位置 */
attr.imgRect.y = 0; /* 0: 图像传感器右上位置 */
attr.imgRect.width = 2592; /* 2592: 图像传感器宽度大小 */
attr.imgRect.height = 1944; /* 1944: 图像传感器高度尺寸 */
/* 写入配置数据 */
ret = MipiCsiSetComboDevAttr(MipiCsiHandle, &attr);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetComboDevAttr fail! ret=%d\n", __func__, ret);
return;
}
/* 共模电压模式参数为0 */
mode = PHY_CMV_GE1200MV;
/* 设备编号为0 */
devno = 0;
/* 设置共模电压模式 */
ret = MipiCsiSetPhyCmvmode(MipiCsiHandle, devno, mode);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiSetPhyCmvmode fail! ret=%d\n", __func__, ret);
return;
}
/* 通路序号为0 */
comboDev = 0;
/* 撤销复位MIPI RX */
ret = MipiCsiUnresetRx(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiUnresetRx fail! ret=%d\n", __func__, ret);
return;
}
/* 关闭MIPI的时钟 */
ret = MipiCsiDisableClock(MipiCsiHandle, comboDev);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiDisableClock fail! ret=%d\n", __func__, ret);
return;
}
/* 传感器撤销复位信号线号为0 */
snsResetSource = 0;
/* 撤销复位sensor */
ret = MipiCsiUnresetSensor(MipiCsiHandle, snsResetSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiUnresetSensor fail! ret=%d\n", __func__, ret);
return;
}
/* 关闭MIPI上的sensor时钟 */
ret = MipiCsiDisableSensorClock(MipiCsiHandle, snsClkSource);
if (ret != 0) {
HDF_LOGE("%s: MipiCsiDisableSensorClock fail! ret=%d\n", __func__, ret);
return;
}
/* 释放MIPI DSI设备句柄 */
MipiCsiClose(MipiCsiHandle);
}
```
# MIPI-CSI<a name="title_MIPI_CSIDevelop"></a>
- [概述](#section1_MIPI_CSIDevelop)
- [开发步骤](#section2_MIPI_CSIDevelop)
- [开发实例](#section3_MIPI_CSIDevelop)
## 概述 <a name="section1_MIPI_CSIDevelop"></a>
CSI(Camera Serial Interface)是由MIPI联盟下Camera工作组指定的接口标准。在HDF框架中,MIPI-CSI的接口适配模式采用无服务模式,用于不需要在用户态提供API的设备类型,或者没有用户态和内核区分的OS系统,MIPI-CSI的接口关联方式是DevHandle直接指向设备对象内核态地址(DevHandle是一个void类型指针)。
图 1 无服务模式结构图
![image1](figures/CSI无服务模式结构图.png)
## 开发步骤 <a name="section2_MIPI_CSIDevelop"></a>
MIPI-CSI模块适配的三个环节是配置属性文件、实例化驱动入、以及实例化核心层接口函数。
1. **实例化驱动入口:**
- 实例化HdfDriverEntry结构体成员。
- 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
2. **配置属性文件:**
- 在device_info.hcs文件中添加deviceNode描述。
- 【可选】添加mipicsi_config.hcs器件属性文件。
3. **实例化MIPICSI控制器对象:**
- 初始化MipiCsiCntlr成员。
- 实例化MipiCsiCntlr成员MipiCsiCntlrMethod,其定义和成员**说明**见下
4. **驱动调试:**
- 【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,数据传输的成功与否等。
> ![](W:\doc\docs\zh-cn\device-dev\public_sys-resources\icon-note.gif) **说明:**
>
> MipiCsiCntlrMethod定义
>
> ```c
> struct MipiCsiCntlrMethod {
> int32_t (*setComboDevAttr)(struct MipiCsiCntlr *cntlr, ComboDevAttr *pAttr);
> int32_t (*setPhyCmvmode)(struct MipiCsiCntlr *cntlr, uint8_t devno, PhyCmvMode cmvMode);
> int32_t (*setExtDataType)(struct MipiCsiCntlr *cntlr, ExtDataType* dataType);
> int32_t (*setHsMode)(struct MipiCsiCntlr *cntlr, LaneDivideMode laneDivideMode);
> int32_t (*enableClock)(struct MipiCsiCntlr *cntlr, uint8_t comboDev);
> int32_t (*disableClock)(struct MipiCsiCntlr *cntlr, uint8_t comboDev);
> int32_t (*resetRx)(struct MipiCsiCntlr *cntlr, uint8_t comboDev);
> int32_t (*unresetRx)(struct MipiCsiCntlr *cntlr, uint8_t comboDev);
> int32_t (*enableSensorClock)(struct MipiCsiCntlr *cntlr, uint8_t snsClkSource);
> int32_t (*disableSensorClock)(struct MipiCsiCntlr *cntlr, uint8_t snsClkSource);
> int32_t (*resetSensor)(struct MipiCsiCntlr *cntlr, uint8_t snsResetSource);
> int32_t (*unresetSensor)(struct MipiCsiCntlr *cntlr, uint8_t snsResetSource);
> };
> ```
>
> 表1 MipiCsiCntlrMethod成员的回调函数功能说明
>
> | 成员函数 | 入参 | 出参 | 返回状态 | 功能 |
> | ------------------ | ------------------------------------------------------------ | ---- | ------------------ | -------------------------- |
> | setComboDevAttr | **cntlr**: 结构体指针,MipiCsi控制器 ;<br>**pAttr**: 结构体指针,MIPI-CSI相应配置结构体指针 | 无 | HDF_STATUS相关状态 | 写入MIPI-CSI配置 |
> | setPhyCmvmode | **cntlr**: 结构体指针,MipiCsi控制器 ;<br>**devno**: uint8_t,设备编号;<br>**cmvMode**: 枚举类型,共模电压模式参数 | 无 | HDF_STATUS相关状态 | 设置共模电压模式 |
> | setExtDataType | **cntlr**: 结构体指针,MipiCsi控制器 ;<br>**dataType**: 结构体指针,定义YUV和原始数据格式以及位深度 | 无 | HDF_STATUS相关状态 | 设置YUV和RAW数据格式和位深 |
> | setHsMode | **cntlr**: 结构体指针,MipiCsi控制器 ;<br>**laneDivideMode**: 枚举类型,lane模式参数 | 无 | HDF_STATUS相关状态 | 设置MIPI RX的 Lane分布 |
> | enableClock | **cntlr**: 结构体指针,MipiCsi控制器 ;<br>**comboDev**: uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 使能mipi的时钟 |
> | disableClock | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**comboDev**: uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 关闭mipi的时钟 |
> | resetRx | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**comboDev**: uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 复位MIPI RX |
> | unresetRx | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**comboDev**: uint8_t,通路序号 | 无 | HDF_STATUS相关状态 | 撤销复位MIPI RX |
> | enableSensorClock | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**: uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 使能mipi上的sensor时钟 |
> | disableSensorClock | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**: uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 关闭mipi上的sensor时钟 |
> | resetSensor | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**: uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 复位sensor |
> | unresetSensor | **cntlr**: 结构体指针,MipiCsi控制器 ;<br/>**snsClkSource**: uint8_t,传感器的时钟信号线号 | 无 | HDF_STATUS相关状态 | 撤销复位sensor |
## 开发实例 <a name="section3_MIPI_CSIDevelop"></a>
下方将以mipi_rx_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。
1. 一般来说,驱动开发首先需要在 busxx_config.hcs 中配置器件属性,并在device_info.hcs文件中添加deviceNode描述。器件属性值与核心层MipiCsiCntlr 成员的默认值或限制范围有密切关系,deviceNode信息与驱动入口注册相关。
**本例中MIPI控制器自身属性在源文件文件中,如有厂商需要,则在device_info文件的deviceNode增加deviceMatchAttr信息,相应增加mipicsi_config.hcs文件**
- device_info.hcs 配置参考
```c
root {
device_info {
match_attr = "hdf_manager";
platform :: host {
hostName = "platform_host";
priority = 50;
device_mipi_csi:: device {
device0 :: deviceNode {
policy = 0;
priority = 160;
permission = 0644;
moduleName = "HDF_MIPI_RX"; //【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致;
serviceName = "HDF_MIPI_RX"; //【必要且唯一】驱动对外发布服务的名称
}
}
}
}
}
```
2. 完成器件属性文件的配置之后,下一步请实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HdfDriverEntry结构体的函数指针成员会被厂商操作函数填充,HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组,方便调用。
一般在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
- MIPI-CSI驱动入口参考
```c
struct HdfDriverEntry g_mipiCsiDriverEntry = {
.moduleVersion = 1,
.Init = Hi35xxMipiCsiInit, //见Init参考
.Release = Hi35xxMipiCsiRelease, //见Release参考
.moduleName = "HDF_MIPI_RX", //【必要】需要与device_info.hcs 中保持一致。
};
HDF_INIT(g_mipiCsiDriverEntry); //调用HDF_INIT将驱动入口注册到HDF框架中
```
3. 完成驱动入口注册之后,最后一步就是以核心层MipiCsiCntlr对象的初始化为核心,实现HdfDriverEntry成员函数(Bind,Init,Release)。MipiCsiCntlr对象的初始化包括厂商自定义结构体(用于传递参数和数据)和实例化MipiCsiCntlr成员MipiCsiCntlrMethod(让用户可以通过接口来调用驱动底层函数)。
- 自定义结构体参考
> 从驱动的角度看,自定义结构体是参数和数据的载体,一般来说,config文件中的数值也会用来初始化结构体成员,本例的mipicsi器件属性在源文件中,故基本成员结构与MipiCsiCntlr无太大差异。
```c
typedef struct {
/** 数据类型:8/10/12/14/16位 */
DataType inputDataType;
/** MIPI波分复用模式 */
MipiWdrMode wdrMode;
/** laneId: -1 - 禁用 */
short laneId[MIPI_LANE_NUM];
union {
/** 用于 HI_MIPI_WDR_MODE_DT */
short dataType[WDR_VC_NUM];
};
} MipiDevAttr;
typedef struct {
/** 设备号 */
uint8_t devno;
/** 输入模式: MIPI/LVDS/SUBLVDS/HISPI/DC */
InputMode inputMode;
MipiDataRate dataRate;
/** MIPI Rx设备裁剪区域(与原始传感器输入图像大小相对应) */
ImgRect imgRect;
union {
MipiDevAttr mipiAttr;
LvdsDevAttr lvdsAttr;
};
} ComboDevAttr;
//MipiCsiCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
struct MipiCsiCntlr {
/** 当驱动程序绑定到HDF框架时,将发送此控制器提供的服务 */
struct IDeviceIoService service;
/** 当驱动程序绑定到HDF框架时,将传入设备端指针 */
struct HdfDeviceObject *device;
/** 设备号 */
unsigned int devNo;
/** 控制器提供的所有接口 */
struct MipiCsiCntlrMethod *ops;
/** 对于控制器调试的所有接口,如果未实现驱动程序,则需要null */
struct MipiCsiCntlrDebugMethod *debugs;
/** 控制器上下文参数变量 */
MipiDevCtx ctx;
/** 访问控制器上下文参数变量时锁定 */
OsalSpinlock ctxLock;
/** 操作控制器时锁定方法 */
struct OsalMutex lock;
/** 匿名数据指针,用于存储csi设备结构 */
void *priv;
};
```
- **【重要】** MipiCsiCntlr成员回调函数结构体MipiCsiCntlrMethod的实例化,其他成员在Init函数中初始化。
```c
static struct MipiCsiCntlrMethod g_method = {
.setComboDevAttr = Hi35xxSetComboDevAttr,
.setPhyCmvmode = Hi35xxSetPhyCmvmode,
.setExtDataType = Hi35xxSetExtDataType,
.setHsMode = Hi35xxSetHsMode,
.enableClock = Hi35xxEnableClock,
.disableClock = Hi35xxDisableClock,
.resetRx = Hi35xxResetRx,
.unresetRx = Hi35xxUnresetRx,
.enableSensorClock = Hi35xxEnableSensorClock,
.disableSensorClock = Hi35xxDisableSensorClock,
.resetSensor = Hi35xxResetSensor,
.unresetSensor = Hi35xxUnresetSensor
};
```
- **Init函数参考**
> **入参:**
> HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息
>
> **返回值:**
> HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)
>
> | 状态(值) | 问题描述 |
> | :--------------------- | :----------: |
> | HDF_ERR_INVALID_OBJECT | 无效对象 |
> | HDF_ERR_MALLOC_FAIL | 内存分配失败 |
> | HDF_ERR_INVALID_PARAM | 无效参数 |
> | HDF_ERR_IO | I/O 错误 |
> | HDF_SUCCESS | 执行成功 |
> | HDF_FAILURE | 执行失败 |
>
> **函数说明:**
> MipiCsiCntlrMethod的实例化对象的挂载,调用MipiCsiRegisterCntlr,以及其他厂商自定义初始化操作。
```c
static int32_t Hi35xxMipiCsiInit(struct HdfDeviceObject *device)
{
int32_t ret;
HDF_LOGI("%s: enter!", __func__);
g_mipiCsi.priv = NULL; //g_mipiTx是定义的全局变量
//static struct MipiCsiCntlr g_mipiCsi = {
//.devNo = 0
//};
g_mipiCsi.ops = &g_method; //MipiCsiCntlrMethod的实例化对象的挂载
#ifdef CONFIG_HI_PROC_SHOW_SUPPORT
g_mipiCsi.debugs = &g_debugMethod;
#endif
ret = MipiCsiRegisterCntlr(&g_mipiCsi, device); //【必要】调用核心层函数和g_mipiTx初始化核心层全局变量
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiCsiRegisterCntlr] failed!", __func__);
return ret;
}
ret = MipiRxDrvInit(); //【必要】厂商对设备的初始化,形式不限
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiRxDrvInit] failed.", __func__);
return ret;
}
#ifdef MIPICSI_VFS_SUPPORT
ret = MipiCsiDevModuleInit(g_mipiCsi.devNo);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: [MipiCsiDevModuleInit] failed!", __func__);
return ret;
}
#endif
OsalSpinInit(&g_mipiCsi.ctxLock);
HDF_LOGI("%s: load mipi csi driver success!", __func__);
return ret;
}
//mipi_dsi_core.c核心层
int32_t MipiCsiRegisterCntlr(struct MipiCsiCntlr *cntlr, struct HdfDeviceObject *device)
{
...
//定义的全局变量:static struct MipiCsiHandle g_mipiCsihandle[MAX_CNTLR_CNT];
if (g_mipiCsihandle[cntlr->devNo].cntlr == NULL) {
(void)OsalMutexInit(&g_mipiCsihandle[cntlr->devNo].lock);
(void)OsalMutexInit(&(cntlr->lock));
g_mipiCsihandle[cntlr->devNo].cntlr = cntlr; //初始化MipiCsiHandle成员
g_mipiCsihandle[cntlr->devNo].priv = NULL;
cntlr->device = device; //使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
device->service = &(cntlr->service); //使HdfDeviceObject与MipiCsiHandle可以相互转化的前提
cntlr->priv = NULL;
HDF_LOGI("%s: success.", __func__);
return HDF_SUCCESS;
}
HDF_LOGE("%s: cntlr already exists.", __func__);
return HDF_FAILURE;
}
```
- **Release函数参考**
> **入参:**
> HdfDeviceObject 是整个驱动对外暴露的接口参数,具备 HCS 配置文件的信息。
>
> **返回值:**
> 无
>
> **函数说明:**
> 该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源,该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作**前提**是在Init函数中具备对应赋值的操作。
```c
static void Hi35xxMipiCsiRelease(struct HdfDeviceObject *device)
{
struct MipiCsiCntlr *cntlr = NULL;
...
cntlr = MipiCsiCntlrFromDevice(device); //这里有HdfDeviceObject到MipiCsiCntlr的强制转化
//return (device == NULL) ? NULL : (struct MipiCsiCntlr *)device->service;
...
OsalSpinDestroy(&cntlr->ctxLock);
#ifdef MIPICSI_VFS_SUPPORT
MipiCsiDevModuleExit(cntlr->devNo);
#endif
MipiRxDrvExit(); //【必要】对厂商设备所占资源的释放
MipiCsiUnregisterCntlr(&g_mipiCsi); //空函数
g_mipiCsi.priv = NULL;
HDF_LOGI("%s: unload mipi csi driver success!", __func__);
}
```
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
使用MIPI-DSI的一般流程如[图2](#fig129103491241)所示。 使用MIPI-DSI的一般流程如[图2](#fig129103491241)所示。
**图 2** MIPI-DSI使用流程图<a name="fig129103491241"></a> **图 2** MIPI-DSI使用流程图<a name="fig129103491241"></a>
![](figures/MIPI-DSI使用流程图.png "MIPI-DSI使用流程图") ![](figures/MIPI-DSI使用流程图.png)
### 获取MIPI-DSI操作句柄<a name="section5126155683811"></a> ### 获取MIPI-DSI操作句柄<a name="section5126155683811"></a>
...@@ -213,7 +213,7 @@ cfg.timingInfo.vsaLines = 76; ...@@ -213,7 +213,7 @@ cfg.timingInfo.vsaLines = 76;
cfg.timingInfo.vfpLines = 120; cfg.timingInfo.vfpLines = 120;
cfg.timingInfo.xResPixels = 1342; cfg.timingInfo.xResPixels = 1342;
/* 写入配置数据 */ /* 写入配置数据 */
ret = MipiDsiSetCfg(g_handle, &cfg); ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
return -1; return -1;
...@@ -265,7 +265,7 @@ int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\); ...@@ -265,7 +265,7 @@ int32\_t MipiDsiGetCfg\(DevHandle handle, struct MipiCfg \*cfg\);
int32_t ret; int32_t ret;
struct MipiCfg cfg; struct MipiCfg cfg;
memset(&cfg, 0, sizeof(struct MipiCfg)); memset(&cfg, 0, sizeof(struct MipiCfg));
ret = MipiDsiGetCfg(g_handle, &cfg); ret = MipiDsiGetCfg(mipiDsiHandle, &cfg);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: GetMipiCfg fail!\n", __func__); HDF_LOGE("%s: GetMipiCfg fail!\n", __func__);
return HDF_FAILURE; return HDF_FAILURE;
...@@ -409,9 +409,9 @@ if (cmdRead->payload == NULL) { ...@@ -409,9 +409,9 @@ if (cmdRead->payload == NULL) {
return HDF_FAILURE; return HDF_FAILURE;
} }
*(cmdRead->payload) = DDIC_REG_STATUS; *(cmdRead->payload) = DDIC_REG_STATUS;
MipiDsiSetLpMode(g_handle); MipiDsiSetLpMode(mipiDsiHandle);
ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal);
MipiDsiSetHsMode(g_handle); MipiDsiSetHsMode(mipiDsiHandle);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
HdfFree(cmdRead->payload); HdfFree(cmdRead->payload);
...@@ -463,13 +463,13 @@ void PalMipiDsiTestSample(void) ...@@ -463,13 +463,13 @@ void PalMipiDsiTestSample(void)
{ {
uint8_t chnId; uint8_t chnId;
int32_t ret; int32_t ret;
DevHandle handle = NULL; DevHandle mipiDsiHandle = NULL;
/* 设备通道编号 */ /* 设备通道编号 */
chnId = 0; chnId = 0;
/* 获取操作句柄 */ /* 获取操作句柄 */
handle = MipiDsiOpen(chnId); mipiDsiHandle = MipiDsiOpen(chnId);
if (handle == NULL) { if (mipiDsiHandle == NULL) {
HDF_LOGE("MipiDsiOpen: failed!\n"); HDF_LOGE("MipiDsiOpen: failed!\n");
return; return;
} }
...@@ -490,7 +490,7 @@ void PalMipiDsiTestSample(void) ...@@ -490,7 +490,7 @@ void PalMipiDsiTestSample(void)
cfg.timingInfo.vfpLines = 120; cfg.timingInfo.vfpLines = 120;
cfg.timingInfo.xResPixels = 1342; cfg.timingInfo.xResPixels = 1342;
/* 写入配置数据 */ /* 写入配置数据 */
ret = MipiDsiSetCfg(g_handle, &cfg); ret = MipiDsiSetCfg(mipiDsiHandle, &cfg);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret); HDF_LOGE("%s: SetMipiCfg fail! ret=%d\n", __func__, ret);
return; return;
...@@ -533,9 +533,9 @@ void PalMipiDsiTestSample(void) ...@@ -533,9 +533,9 @@ void PalMipiDsiTestSample(void)
return; return;
} }
*(cmdRead->payload) = DDIC_REG_STATUS; *(cmdRead->payload) = DDIC_REG_STATUS;
MipiDsiSetLpMode(g_handle); MipiDsiSetLpMode(mipiDsiHandle);
ret = MipiDsiRx(g_handle, cmdRead, sizeof(readVal), &readVal); ret = MipiDsiRx(mipiDsiHandle, cmdRead, sizeof(readVal), &readVal);
MipiDsiSetHsMode(g_handle); MipiDsiSetHsMode(mipiDsiHandle);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret); HDF_LOGE("%s: MipiDsiRx fail! ret=%d\n", __func__, ret);
HdfFree(cmdRead->payload); HdfFree(cmdRead->payload);
......
# PWM<a name="ZH-CN_TOPIC_0000001160812684"></a> # PWM<a name="title_PWM_des"></a>
- [概述](#section1043395117296) - [概述](#section1_PWM_des)
- [接口说明](#section3939192652418) - [PwmConfig结构体](#section1.1_PWM_des)
- [使用指导](#section435718267334) - [接口说明](#section2_PWM_des)
- [使用流程](#section113655616347) - [使用指导](#section3_PWM_des)
- [获取PWM设备句柄](#section17816586359) - [使用流程](#section3.1_PWM_des)
- [设置PWM周期](#section920214812397) - [获取PWM设备句柄](#section3.2_PWM_des)
- [设置PWM占空比](#section519712820405) - [销毁PWM设备句柄](#section3.3_PWM_des)
- [设置PWM极性](#section12383334115) - [使能](#section3.4_PWM_des)
- [使能PWM](#section382684811414) - [禁用](#section3.5_PWM_des)
- [禁用PWM](#section16545114404218) - [设置PWM设备周期](#section3.6_PWM_des)
- [获取PWM设备配置信息](#section117101243144311) - [设置PWM设备占空时间](#section3.7_PWM_des)
- [设置PWM设备配置信息](#section13834163604414) - [设置PWM设备极性](#section3.8_PWM_des)
- [释放PWM设备句柄](#section12987111511450) - [设置PWM设备参数](#section3.9_PWM_des)
- [获取PWM设备参数](#section3.10_PWM_des)
- [使用实例](#section138636719469)
- [使用实例](#section3_PWM_des)
## 概述<a name="section1043395117296"></a>
## 概述<a name="section1_PWM_des"></a>
PWM是脉冲宽度调制(Pulse Width Modulation)的缩写,是一种对模拟信号电平进行数字编码并将其转换为脉冲的技术。常用于马达控制、背光亮度调节等。
- PWM是脉冲宽度调制(Pulse Width Modulation)的缩写,是一种对模拟信号电平进行数字编码,转换为脉冲的一种技术。常用于马达控制、背光亮度调节等。
PWM接口定义了操作PWM设备的通用方法集合,包括:
- PWM接口定义了操作PWM设备的通用方法集合,包括:
- PWM设备句柄获取和释放。 - PWM设备句柄获取和销毁。
- PWM周期、占空比、极性的设置。 - PWM周期、占空比、极性的设置。
- PWM使能和关闭。 - PWM使能和关闭。
- PWM配置信息的获取和设置 - PWM配置信息的获取和设置
## 接口说明<a name="section3939192652418"></a> ### PwmConfig结构体<a name="section1.1_PWM_des"></a>
**表 1** PWM驱动API接口功能介绍 **表1** PwmConfig结构体介绍
<a name="table1731550155318"></a> <a name="table1_PWM_des"></a>
<table><thead align="left"><tr id="row4419501537"><th class="cellrowborder" align="left" valign="top" width="20.857914208579142%" id="mcps1.2.4.1.1"><p id="p641050105320"><a name="p641050105320"></a><a name="p641050105320"></a>功能分类</p>
</th> | 名称 | 描述 |
<th class="cellrowborder" align="left" valign="top" width="23.36766323367663%" id="mcps1.2.4.1.2"><p id="p54150165315"><a name="p54150165315"></a><a name="p54150165315"></a>接口名</p> | -------- | ------------------------------------------------------------ |
</th> | duty | 占空时间,以纳秒为单位 |
<th class="cellrowborder" align="left" valign="top" width="55.77442255774422%" id="mcps1.2.4.1.3"><p id="p941150145313"><a name="p941150145313"></a><a name="p941150145313"></a>描述</p> | period | PWM周期,以纳秒为单位 |
</th> | number | 要生成的方波数。正值表示将生成指定数量的方波,<b>0</b>表示方波将不断产生 |
</tr> | polarity | 极性:正极性/反极性 |
</thead> | status | 状态:启用状态/禁用状态 |
<tbody><tr id="row1651292212306"><td class="cellrowborder" rowspan="2" valign="top" width="20.857914208579142%" headers="mcps1.2.4.1.1 "><p id="p1387414255305"><a name="p1387414255305"></a><a name="p1387414255305"></a>PWM设备句柄获取和释放</p>
</td> ## 接口说明<a name="section2_PWM_des"></a>
<td class="cellrowborder" valign="top" width="23.36766323367663%" headers="mcps1.2.4.1.2 "><p id="p8874825143014"><a name="p8874825143014"></a><a name="p8874825143014"></a>PwmOpen</p>
</td> **表2** PWM设备API接口功能介绍
<td class="cellrowborder" valign="top" width="55.77442255774422%" headers="mcps1.2.4.1.3 "><p id="p1087432513307"><a name="p1087432513307"></a><a name="p1087432513307"></a>获取PWM设备句柄</p>
</td> <a name="table2_PWM_des"></a>
</tr>
<tr id="row1429083612305"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1956614106311"><a name="p1956614106311"></a><a name="p1956614106311"></a>PwmClose</p> <table border="0" cellpadding="0" cellspacing="0" width="800" style="border-collapse:
</td> collapse;table-layout:fixed;width:700pt">
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p829111362306"><a name="p829111362306"></a><a name="p829111362306"></a>释放PWM设备句柄</p> <colgroup><col class="xl65" width="300" style="mso-width-source:userset;mso-width-alt:13728;
</td> width:300pt">
</tr> <col width="250" style="mso-width-source:userset;mso-width-alt:13216;width:250pt">
<tr id="row34145016535"><td class="cellrowborder" rowspan="3" valign="top" width="20.857914208579142%" headers="mcps1.2.4.1.1 "><p id="p229610227124"><a name="p229610227124"></a><a name="p229610227124"></a>PWM周期、占空比、极性的设置</p> <col width="300" style="mso-width-source:userset;mso-width-alt:28352;width:300pt">
</td> </colgroup><tbody><tr height="19" style="height:14.25pt">
<td class="cellrowborder" valign="top" width="23.36766323367663%" headers="mcps1.2.4.1.2 "><p id="p19389143041518"><a name="p19389143041518"></a><a name="p19389143041518"></a>PwmSetPeriod</p> <td height="19" class="xl66" width="300" style="height:14.25pt;width:300pt">功能分类</td>
</td> <td class="xl67" width="250" style="width:250pt">接口名</td>
<td class="cellrowborder" valign="top" width="55.77442255774422%" headers="mcps1.2.4.1.3 "><p id="p1360544321811"><a name="p1360544321811"></a><a name="p1360544321811"></a>设置PWM周期</p> <td class="xl67" width="300" style="width:300pt">描述</td>
</td> </tr>
</tr> <tr height="19" style="height:14.25pt">
<tr id="row5632152611414"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1392810111722"><a name="p1392810111722"></a><a name="p1392810111722"></a>PwmSetDuty</p> <td rowspan="2" height="38" class="xl65" style="height:28.5pt">PWM句柄操作</td>
</td> <td>PwmOpen</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p10448193611188"><a name="p10448193611188"></a><a name="p10448193611188"></a>设置PWM占空比</p> <td>获取PWM设备驱动句柄</td>
</td> </tr>
</tr> <tr height="19" style="height:14.25pt">
<tr id="row1766145611414"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p10445141911213"><a name="p10445141911213"></a><a name="p10445141911213"></a>PwmSetPolarity</p> <td height="19" style="height:14.25pt">PwmClose</td>
</td> <td>释放PWM设备驱动句柄</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p448643019188"><a name="p448643019188"></a><a name="p448643019188"></a>设置PWM极性</p> </tr>
</td> <tr height="19" style="height:14.25pt">
</tr> <td rowspan="2" height="38" class="xl65" style="height:28.5pt">使能/禁用PWM</td>
<tr id="row195531331436"><td class="cellrowborder" rowspan="2" valign="top" width="20.857914208579142%" headers="mcps1.2.4.1.1 "><p id="p166091535331"><a name="p166091535331"></a><a name="p166091535331"></a>PWM使能和关闭</p> <td>PwmEnable</td>
</td> <td>使能PWM</td>
<td class="cellrowborder" valign="top" width="23.36766323367663%" headers="mcps1.2.4.1.2 "><p id="p85533315315"><a name="p85533315315"></a><a name="p85533315315"></a>PwmEnable</p> </tr>
</td> <tr height="19" style="height:14.25pt">
<td class="cellrowborder" valign="top" width="55.77442255774422%" headers="mcps1.2.4.1.3 "><p id="p855303118314"><a name="p855303118314"></a><a name="p855303118314"></a>使能PWM</p> <td height="19" style="height:14.25pt">PwmDisable</td>
</td> <td>禁用PWM</td>
</tr> </tr>
<tr id="row96141928233"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p66151828330"><a name="p66151828330"></a><a name="p66151828330"></a>PwmDisable</p> <tr height="19" style="height:14.25pt">
</td> <td rowspan="3" height="57" class="xl65" style="height:42.75pt">PWM配置操作</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p261518281139"><a name="p261518281139"></a><a name="p261518281139"></a>禁用PWM</p> <td>PwmSetPeriod</td>
</td> <td>设置PWM周期</td>
</tr> </tr>
<tr id="row1020919129159"><td class="cellrowborder" rowspan="2" valign="top" width="20.857914208579142%" headers="mcps1.2.4.1.1 "><p id="p82092126154"><a name="p82092126154"></a><a name="p82092126154"></a>PWM配置信息的获取和设置</p> <tr height="19" style="height:14.25pt">
<p id="p6794153701111"><a name="p6794153701111"></a><a name="p6794153701111"></a></p> <td height="19" style="height:14.25pt">PwmSetDuty</td>
</td> <td>设置PWM占空时间</td>
<td class="cellrowborder" valign="top" width="23.36766323367663%" headers="mcps1.2.4.1.2 "><p id="p1739013012154"><a name="p1739013012154"></a><a name="p1739013012154"></a>PwmSetConfig</p> </tr>
</td> <tr height="19" style="height:14.25pt">
<td class="cellrowborder" valign="top" width="55.77442255774422%" headers="mcps1.2.4.1.3 "><p id="p1152912417189"><a name="p1152912417189"></a><a name="p1152912417189"></a>设置PWM设备配置信息</p> <td height="19" style="height:14.25pt">PwmSetPolarity</td>
</td> <td>设置PWM极性</td>
</tr> </tr>
<tr id="row379443710118"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p4333154919111"><a name="p4333154919111"></a><a name="p4333154919111"></a>PwmGetConfig</p> <tr height="19" style="height:14.25pt">
</td> <td rowspan="2" height="38" class="xl65" style="height:28.5pt">设置/获取PWM配置信息</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p19575195601711"><a name="p19575195601711"></a><a name="p19575195601711"></a>获取PWM设备配置信息</p> <td>PwmSetConfig</td>
</td> <td>设置PWM设备参数</td>
</tr> </tr>
</tbody> <tr height="19" style="height:14.25pt">
</table> <td height="19" style="height:14.25pt">PwmGetConfig</td>
<td>获取PWM设备参数</td>
>![](../public_sys-resources/icon-note.gif) **说明:** </tr>
>本文涉及的所有接口,仅限内核态使用,不支持在用户态使用。 <!--[if supportMisalignedColumns]-->
<tr height="0" style="display:none">
## 使用指导<a name="section435718267334"></a> <td width="429" style="width:322pt"></td>
<td width="413" style="width:310pt"></td>
### 使用流程<a name="section113655616347"></a> <td width="886" style="width:665pt"></td>
</tr>
使用PWM的一般流程如[图1](#fig23885455594)所示。 <!--[endif]-->
</tbody></table>
**图 1** PWM使用流程图<a name="fig23885455594"></a>
![](figures/zh-cn_image_0000001206372673.png) >![](W:\doc\docs\zh-cn\device-dev\public_sys-resources\icon-note.gif) **说明:**
>PWM当前仅限内核态使用,不支持在用户态使用。
### 获取PWM设备句柄<a name="section17816586359"></a>
## 使用指导<a name="section3_PWM_des"></a>
### 使用流程<a name="section3.1_PWM_des"></a>
在操作系统启动过程中,驱动管理模块根据配置文件加载PWM驱动,PWM驱动会检测PWM器件并初始化驱动。
使用PWM设备的一般流程如[图1](#fig1_PWM_des)所示。
**图 1** PWM设备使用流程图<a name="fig1_PWM_des"></a>
![](figures/PWM设备使用流程图.png)
### 获取PWM设备句柄<a name="section3.2_PWM_des"></a>
在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。 在操作PWM设备时,首先要调用PwmOpen获取PWM设备句柄,该函数会返回指定设备号的PWM设备句柄。
DevHandle PwmOpen\(uint32\_t num\); ```c
DevHandle PwmOpen(uint32_t num);
**表 2** PwmOpen参数和返回值描述
<a name="table7603619123820"></a>
<table><tbody><tr id="row1060351914386"><td class="cellrowborder" valign="top" width="50%"><p id="p14603181917382"><a name="p14603181917382"></a><a name="p14603181917382"></a><strong id="b743851872411"><a name="b743851872411"></a><a name="b743851872411"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p36031519183819"><a name="p36031519183819"></a><a name="p36031519183819"></a><strong id="b545016183242"><a name="b545016183242"></a><a name="b545016183242"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row1960431983813"><td class="cellrowborder" valign="top" width="50%"><p id="p1114111239269"><a name="p1114111239269"></a><a name="p1114111239269"></a>num</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1560441923818"><a name="p1560441923818"></a><a name="p1560441923818"></a>PWM设备号</p>
</td>
</tr>
<tr id="row380484160"><td class="cellrowborder" valign="top" width="50%"><p id="p460381915385"><a name="p460381915385"></a><a name="p460381915385"></a><strong id="b209091422131617"><a name="b209091422131617"></a><a name="b209091422131617"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p96031619153812"><a name="p96031619153812"></a><a name="p96031619153812"></a><strong id="b126401632121619"><a name="b126401632121619"></a><a name="b126401632121619"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row5793818161"><td class="cellrowborder" valign="top" width="50%"><p id="p1060418195389"><a name="p1060418195389"></a><a name="p1060418195389"></a>NULL</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p760471912388"><a name="p760471912388"></a><a name="p760471912388"></a>获取PWM设备句柄失败</p>
</td>
</tr>
<tr id="row187914871618"><td class="cellrowborder" valign="top" width="50%"><p id="p5604719133811"><a name="p5604719133811"></a><a name="p5604719133811"></a>设备句柄</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p3604181933818"><a name="p3604181933818"></a><a name="p3604181933818"></a>对应的PWM设备句柄</p>
</td>
</tr>
</tbody>
</table>
假设系统中的PWM设备号为0,获取该PWM设备句柄的示例如下:
``` ```
**表3** PwmOpen参数和返回值描述
<a name="table3_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | ----------------------- |
| void | NA |
| num | PWM设备编号 |
| **返回值** | **返回值描述** |
| handle | 获取成功返回PWM设备句柄 |
| NULL | 获取失败 |
```c
uint32_t num = 0; /* PWM设备号 */ uint32_t num = 0; /* PWM设备号 */
DevHandle pwm = NULL; /* PWM设备句柄 / DevHandle handle = NULL;
/* 获取PWM设备句柄 */ /* 获取PWM设备句柄 */
pwm = PwmOpen(num); handle = PwmOpen(num);
if (pwm == NULL) { if (handle == NULL) {
HDF_LOGE("PwmOpen: pwm%d failed", num); /* 错误处理 */
return;
} }
``` ```
### 设置PWM周期<a name="section920214812397"></a> ### 销毁PWM设备句柄<a name="section3.3_PWM_des"></a>
int32\_t PwmSetPeriod\(DevHandle handle, uint32\_t period\); 关闭PWM设备,系统释放对应的资源。
**表 3** PwmSetPeriod参数和返回值描述
<a name="table16124612193214"></a>
<table><tbody><tr id="row4124212123217"><td class="cellrowborder" valign="top" width="50%"><p id="p11124131243218"><a name="p11124131243218"></a><a name="p11124131243218"></a><strong id="b6124201293218"><a name="b6124201293218"></a><a name="b6124201293218"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p14124191263210"><a name="p14124191263210"></a><a name="p14124191263210"></a><strong id="b1712481273218"><a name="b1712481273218"></a><a name="b1712481273218"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row111241012133210"><td class="cellrowborder" valign="top" width="50%"><p id="p18124201220324"><a name="p18124201220324"></a><a name="p18124201220324"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p20124191210321"><a name="p20124191210321"></a><a name="p20124191210321"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row151241112163216"><td class="cellrowborder" valign="top" width="50%"><p id="p712481223212"><a name="p712481223212"></a><a name="p712481223212"></a>period</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1312411126320"><a name="p1312411126320"></a><a name="p1312411126320"></a>周期,单位纳秒</p>
</td>
</tr>
<tr id="row712471214320"><td class="cellrowborder" valign="top" width="50%"><p id="p1612421233217"><a name="p1612421233217"></a><a name="p1612421233217"></a><strong id="b1512411293212"><a name="b1512411293212"></a><a name="b1512411293212"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1712591211327"><a name="p1712591211327"></a><a name="p1712591211327"></a><strong id="b121252012153217"><a name="b121252012153217"></a><a name="b121252012153217"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row812581214326"><td class="cellrowborder" valign="top" width="50%"><p id="p13125812183214"><a name="p13125812183214"></a><a name="p13125812183214"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p15125812193212"><a name="p15125812193212"></a><a name="p15125812193212"></a>设置周期成功</p>
</td>
</tr>
<tr id="row2012571273216"><td class="cellrowborder" valign="top" width="50%"><p id="p17125181215327"><a name="p17125181215327"></a><a name="p17125181215327"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p81251512143217"><a name="p81251512143217"></a><a name="p81251512143217"></a>设置周期失败</p>
</td>
</tr>
</tbody>
</table>
```c
void PwmClose(DevHandle handle);
``` ```
int32_t ret;
uint32_t period = 1000; /* 周期1000纳秒 */ **表4** PwmClose参数描述
ret = PwmSetPeriod(pwm, period); /* 设置PWM周期 */
if (ret != 0) { <a name="table4_PWM_des"></a>
HDF_LOGE("PwmSetPeriod: failed, ret %d", ret);
} | 参数 | 参数描述 |
| ------ | ----------- |
| handle | PWM设备句柄 |
```c
/* 销毁PWM设备句柄 */
PwmClose(handle);
``` ```
### 设置PWM占空比<a name="section519712820405"></a> ### 使能<a name="section3.4_PWM_des"></a>
int32\_t PwmSetDuty\(DevHandle handle, uint32\_t duty\); 启用PWM设备。
**表 4** PwmSetDuty参数和返回值描述
<a name="table2010731215368"></a>
<table><tbody><tr id="row51071812163614"><td class="cellrowborder" valign="top" width="50%"><p id="p21071412123617"><a name="p21071412123617"></a><a name="p21071412123617"></a><strong id="b1710731216361"><a name="b1710731216361"></a><a name="b1710731216361"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p910715125363"><a name="p910715125363"></a><a name="p910715125363"></a><strong id="b7107212113610"><a name="b7107212113610"></a><a name="b7107212113610"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row5107912193611"><td class="cellrowborder" valign="top" width="50%"><p id="p15107141223618"><a name="p15107141223618"></a><a name="p15107141223618"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p16107151293612"><a name="p16107151293612"></a><a name="p16107151293612"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row131077122364"><td class="cellrowborder" valign="top" width="50%"><p id="p4107161218361"><a name="p4107161218361"></a><a name="p4107161218361"></a>duty</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p13107201263620"><a name="p13107201263620"></a><a name="p13107201263620"></a>占空比,单位纳秒</p>
</td>
</tr>
<tr id="row161071512143618"><td class="cellrowborder" valign="top" width="50%"><p id="p01071012123617"><a name="p01071012123617"></a><a name="p01071012123617"></a><strong id="b11076127365"><a name="b11076127365"></a><a name="b11076127365"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p10107111273619"><a name="p10107111273619"></a><a name="p10107111273619"></a><strong id="b5108312123619"><a name="b5108312123619"></a><a name="b5108312123619"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row15108101217363"><td class="cellrowborder" valign="top" width="50%"><p id="p1110811263616"><a name="p1110811263616"></a><a name="p1110811263616"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p61081712203612"><a name="p61081712203612"></a><a name="p61081712203612"></a>设置占空比成功</p>
</td>
</tr>
<tr id="row171081012183618"><td class="cellrowborder" valign="top" width="50%"><p id="p610816120365"><a name="p610816120365"></a><a name="p610816120365"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p10108012143617"><a name="p10108012143617"></a><a name="p10108012143617"></a>设置占空比失败</p>
</td>
</tr>
</tbody>
</table>
```c
int32_t PwmEnable(DevHandle handle);
``` ```
**表5** PwmEnable参数描述
<a name="table5_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | -------------- |
| handle | PWM设备句柄 |
| **返回值** | **返回值描述** |
| 0 | 使能成功 |
| 负数 | 使能失败 |
```c
int32_t ret; int32_t ret;
uint32_t duty = 500; /* 占空比500纳秒 */
ret = PwmSetDuty(pwm, duty); /* 设置PWM占空比 */ /*启用PWM设备*/
ret = PwmEnable(handle);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmSetDuty: failed, ret %d", ret); /*错误处理*/
} }
``` ```
### 设置PWM极性<a name="section12383334115"></a> ### 禁用<a name="section3.5_PWM_des"></a>
int32\_t PwmSetPolarity\(DevHandle handle, uint8\_t polarity\); 禁用PWM设备。
**表 5** PwmSetPolarity参数和返回值描述
<a name="table141853773813"></a>
<table><tbody><tr id="row6418837183810"><td class="cellrowborder" valign="top" width="50%"><p id="p14181637103817"><a name="p14181637103817"></a><a name="p14181637103817"></a><strong id="b4418537123810"><a name="b4418537123810"></a><a name="b4418537123810"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p74181375386"><a name="p74181375386"></a><a name="p74181375386"></a><strong id="b1541810373380"><a name="b1541810373380"></a><a name="b1541810373380"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row84181437163812"><td class="cellrowborder" valign="top" width="50%"><p id="p1141823715384"><a name="p1141823715384"></a><a name="p1141823715384"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p7418143718385"><a name="p7418143718385"></a><a name="p7418143718385"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row5418123711387"><td class="cellrowborder" valign="top" width="50%"><p id="p241893773817"><a name="p241893773817"></a><a name="p241893773817"></a>polarity</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p184181937123811"><a name="p184181937123811"></a><a name="p184181937123811"></a>极性,PWM_NORMAL_POLARITY为正常极性,PWM_INVERTED_POLARITY为反转极性。</p>
</td>
</tr>
<tr id="row841883773819"><td class="cellrowborder" valign="top" width="50%"><p id="p11418193763820"><a name="p11418193763820"></a><a name="p11418193763820"></a><strong id="b3418123713810"><a name="b3418123713810"></a><a name="b3418123713810"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p164185378387"><a name="p164185378387"></a><a name="p164185378387"></a><strong id="b341816371384"><a name="b341816371384"></a><a name="b341816371384"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row1741919372382"><td class="cellrowborder" valign="top" width="50%"><p id="p2419103718389"><a name="p2419103718389"></a><a name="p2419103718389"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p241993723818"><a name="p241993723818"></a><a name="p241993723818"></a>设置极性成功</p>
</td>
</tr>
<tr id="row1441983711384"><td class="cellrowborder" valign="top" width="50%"><p id="p1441903793817"><a name="p1441903793817"></a><a name="p1441903793817"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p84191237193817"><a name="p84191237193817"></a><a name="p84191237193817"></a>设置极性失败</p>
</td>
</tr>
</tbody>
</table>
```c
int32_t PwmDisable(DevHandle handle);
``` ```
**表6** PwmDisable参数描述
<a name="table6_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | -------------- |
| handle | PWM设备句柄 |
| **返回值** | **返回值描述** |
| 0 | 禁用成功 |
| 负数 | 禁用失败 |
```c
int32_t ret; int32_t ret;
uint8_t polarity = PWM_INVERTED_POLARITY; /* 反转极性 */
ret = PwmSetPolarity(pwm, polarity); /* 设置PWM反转极性 */ /*禁用PWM设备*/
ret = PwmDisable(handle);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmSetPolarity: failed, ret %d", ret); /*错误处理*/
} }
``` ```
### 使能PWM<a name="section382684811414"></a> ### 设置PWM设备周期<a name="section3.6_PWM_des"></a>
int32\_t PwmEnable\(DevHandle handle\);
**表 6** PwmEnable参数和返回值描述
<a name="table785385210447"></a>
<table><tbody><tr id="row9853185234417"><td class="cellrowborder" valign="top" width="50%"><p id="p7853195215444"><a name="p7853195215444"></a><a name="p7853195215444"></a><strong id="b685318525446"><a name="b685318525446"></a><a name="b685318525446"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p4853352104417"><a name="p4853352104417"></a><a name="p4853352104417"></a><strong id="b19853752174418"><a name="b19853752174418"></a><a name="b19853752174418"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row6853165254419"><td class="cellrowborder" valign="top" width="50%"><p id="p085313525446"><a name="p085313525446"></a><a name="p085313525446"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p185319529444"><a name="p185319529444"></a><a name="p185319529444"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row585313527443"><td class="cellrowborder" valign="top" width="50%"><p id="p15853652174416"><a name="p15853652174416"></a><a name="p15853652174416"></a><strong id="b17853252124418"><a name="b17853252124418"></a><a name="b17853252124418"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1385310525444"><a name="p1385310525444"></a><a name="p1385310525444"></a><strong id="b78541952104416"><a name="b78541952104416"></a><a name="b78541952104416"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row9854252134410"><td class="cellrowborder" valign="top" width="50%"><p id="p13854155214416"><a name="p13854155214416"></a><a name="p13854155214416"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p6854452114416"><a name="p6854452114416"></a><a name="p6854452114416"></a>使能PWM成功</p>
</td>
</tr>
<tr id="row58545526443"><td class="cellrowborder" valign="top" width="50%"><p id="p1085412522449"><a name="p1085412522449"></a><a name="p1085412522449"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p2854052124416"><a name="p2854052124416"></a><a name="p2854052124416"></a>使能PWM失败</p>
</td>
</tr>
</tbody>
</table>
设置PWM设备周期。
```c
int32_t PwmSetPeriod(DevHandle handle, uint32_t period);
``` ```
**表7** PwmSetPeriod参数描述
<a name="table7_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | ------------------------ |
| handle | PWM设备句柄 |
| period | 要设置的周期,单位为纳秒 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret; int32_t ret;
ret = PwmEnable(pwm); /* 使能PWM */
/*设置周期为50000000纳秒*/
ret = PwmSetPeriod(handle, 50000000);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmEnable: failed, ret %d", ret); /*错误处理*/
} }
``` ```
### 设置PWM设备占空时间<a name="section3.7_PWM_des"></a>
### 禁用PWM<a name="section16545114404218"></a> 设置PWM设备占空时间。
int32\_t PwmDisable\(DevHandle handle\);
**表 7** PwmDisable参数和返回值描述
<a name="table1354973912475"></a>
<table><tbody><tr id="row115499392478"><td class="cellrowborder" valign="top" width="50%"><p id="p1554993912474"><a name="p1554993912474"></a><a name="p1554993912474"></a><strong id="b655018395479"><a name="b655018395479"></a><a name="b655018395479"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p055083915471"><a name="p055083915471"></a><a name="p055083915471"></a><strong id="b185507390472"><a name="b185507390472"></a><a name="b185507390472"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row1855093974715"><td class="cellrowborder" valign="top" width="50%"><p id="p2550739114717"><a name="p2550739114717"></a><a name="p2550739114717"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1755018397479"><a name="p1755018397479"></a><a name="p1755018397479"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row355043910472"><td class="cellrowborder" valign="top" width="50%"><p id="p1655053984714"><a name="p1655053984714"></a><a name="p1655053984714"></a><strong id="b755043920479"><a name="b755043920479"></a><a name="b755043920479"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p16550439154720"><a name="p16550439154720"></a><a name="p16550439154720"></a><strong id="b1055053918475"><a name="b1055053918475"></a><a name="b1055053918475"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row25507391479"><td class="cellrowborder" valign="top" width="50%"><p id="p1555014394473"><a name="p1555014394473"></a><a name="p1555014394473"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p15550839174713"><a name="p15550839174713"></a><a name="p15550839174713"></a>关闭PWM成功</p>
</td>
</tr>
<tr id="row1155093913470"><td class="cellrowborder" valign="top" width="50%"><p id="p1655015398476"><a name="p1655015398476"></a><a name="p1655015398476"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p4550143919471"><a name="p4550143919471"></a><a name="p4550143919471"></a>关闭PWM失败</p>
</td>
</tr>
</tbody>
</table>
```c
int32_t PwmSetDuty(DevHandle handle, uint32_t duty);
``` ```
**表8** PwmSetDuty参数描述
<a name="table8_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | ---------------------------- |
| handle | PWM设备句柄 |
| duty | 要设置的占空时间,单位为纳秒 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret; int32_t ret;
ret = PwmDisable(pwm); /* 禁用PWM */
/*设置占空时间为25000000纳秒*/
ret = PwmSetDuty(handle, 25000000);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmDisable: failed, ret %d", ret); /*错误处理*/
} }
``` ```
### 设置PWM设备极性<a name="section3.8_PWM_des"></a>
### 获取PWM设备配置信息<a name="section117101243144311"></a> 设置PWM设备极性。
int32\_t PwmGetConfig\(DevHandle handle, struct PwmConfig \*config\);
**表 8** PwmGetConfig参数和返回值描述
<a name="table14209152141313"></a>
<table><tbody><tr id="row1420918529133"><td class="cellrowborder" valign="top" width="50%"><p id="p42091852141314"><a name="p42091852141314"></a><a name="p42091852141314"></a><strong id="b2209135217139"><a name="b2209135217139"></a><a name="b2209135217139"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p202099523137"><a name="p202099523137"></a><a name="p202099523137"></a><strong id="b16209195201319"><a name="b16209195201319"></a><a name="b16209195201319"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row142091352171310"><td class="cellrowborder" valign="top" width="50%"><p id="p1520915529131"><a name="p1520915529131"></a><a name="p1520915529131"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p720995291310"><a name="p720995291310"></a><a name="p720995291310"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row6209152161314"><td class="cellrowborder" valign="top" width="50%"><p id="p720916522139"><a name="p720916522139"></a><a name="p720916522139"></a>config</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p172091452131319"><a name="p172091452131319"></a><a name="p172091452131319"></a>PWM设备配置信息</p>
</td>
</tr>
<tr id="row12092522139"><td class="cellrowborder" valign="top" width="50%"><p id="p18209125211134"><a name="p18209125211134"></a><a name="p18209125211134"></a><strong id="b2209155219132"><a name="b2209155219132"></a><a name="b2209155219132"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p420975231318"><a name="p420975231318"></a><a name="p420975231318"></a><strong id="b4209165210132"><a name="b4209165210132"></a><a name="b4209165210132"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row8209155251310"><td class="cellrowborder" valign="top" width="50%"><p id="p13210145291312"><a name="p13210145291312"></a><a name="p13210145291312"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p152101952141315"><a name="p152101952141315"></a><a name="p152101952141315"></a>获取配置成功</p>
</td>
</tr>
<tr id="row102101452121320"><td class="cellrowborder" valign="top" width="50%"><p id="p10210175219134"><a name="p10210175219134"></a><a name="p10210175219134"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p72101252101312"><a name="p72101252101312"></a><a name="p72101252101312"></a>获取配置失败</p>
</td>
</tr>
</tbody>
</table>
```c
int32_t PwmSetPolarity(DevHandle handle, uint8_t polarity);
``` ```
**表9** PwmSetPolarity参数描述
<a name="table9_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | ------------------- |
| handle | PWM设备句柄 |
| polarity | 要设置的极性,正/反 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret; int32_t ret;
struct PwmConfig config= {0}; /* PWM配置信息 */
ret = PwmGetConfig(pwm, &config); /* 获取PWM设备配置信息 */ /*设置极性为反*/
ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmGetConfig: failed, ret %d", ret); /*错误处理*/
} }
``` ```
### 设置PWM设备配置信息<a name="section13834163604414"></a>
int32\_t PwmSetConfig\(DevHandle handle, struct PwmConfig \*config\);
**表 9** PwmSetConfig参数和返回值描述
<a name="table1836117542321"></a>
<table><tbody><tr id="row20361165453211"><td class="cellrowborder" valign="top" width="50%"><p id="p1736135418323"><a name="p1736135418323"></a><a name="p1736135418323"></a><strong id="b236115412323"><a name="b236115412323"></a><a name="b236115412323"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p13361954103214"><a name="p13361954103214"></a><a name="p13361954103214"></a><strong id="b16361185433217"><a name="b16361185433217"></a><a name="b16361185433217"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row336185416328"><td class="cellrowborder" valign="top" width="50%"><p id="p3361454153218"><a name="p3361454153218"></a><a name="p3361454153218"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p836175418328"><a name="p836175418328"></a><a name="p836175418328"></a>PWM设备句柄</p>
</td>
</tr>
<tr id="row18361135411322"><td class="cellrowborder" valign="top" width="50%"><p id="p2036175403217"><a name="p2036175403217"></a><a name="p2036175403217"></a>config</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p1736120541323"><a name="p1736120541323"></a><a name="p1736120541323"></a>PWM设备配置信息</p>
</td>
</tr>
<tr id="row2361254133217"><td class="cellrowborder" valign="top" width="50%"><p id="p1636295463212"><a name="p1636295463212"></a><a name="p1636295463212"></a><strong id="b13622054133219"><a name="b13622054133219"></a><a name="b13622054133219"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p173621854153217"><a name="p173621854153217"></a><a name="p173621854153217"></a><strong id="b15362195410326"><a name="b15362195410326"></a><a name="b15362195410326"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row73628543328"><td class="cellrowborder" valign="top" width="50%"><p id="p15362205417325"><a name="p15362205417325"></a><a name="p15362205417325"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p436285433211"><a name="p436285433211"></a><a name="p436285433211"></a>设置配置成功</p>
</td>
</tr>
<tr id="row23621154153220"><td class="cellrowborder" valign="top" width="50%"><p id="p13362954113214"><a name="p13362954113214"></a><a name="p13362954113214"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p83629546325"><a name="p83629546325"></a><a name="p83629546325"></a>设置配置失败</p>
</td>
</tr>
</tbody>
</table>
### 设置PWM设备参数<a name="section3.9_PWM_des"></a>
设置PWM设备参数。
```c
int32_t PwmSetConfig(DevHandle handle, struct PwmConfig *config);
``` ```
**表10** PwmSetConfig参数描述
<a name="table10_PWM_des"></a>
| 参数 | 参数描述 |
| ---------- | -------------- |
| handle | PWM设备句柄 |
| *config | 参数指针 |
| **返回值** | **返回值描述** |
| 0 | 设置成功 |
| 负数 | 设置失败 |
```c
int32_t ret; int32_t ret;
struct PwmConfig config= {0}; /* PWM配置信息 */ struct PwmConfig pcfg;
config.duty = 500; /* 占空比500纳秒 */ pcfg.duty = 25000000; /*占空时间为25000000纳秒*/
config.period = 1000; /* 周期1000纳秒 */ pcfg.period = 50000000; /*周期为50000000纳秒*/
config.number = 0; /* 一直输出方波 */ pcfg.number = 0; /*不断产生方波*/
config.polarity = PWM_NORMAL_POLARITY; /* 正常极性 */ pcfg.polarity = PWM_INVERTED_POLARITY; /*极性为反*/
ret = PwmSetConfig(pwm, &config); /* 设置PWM设备配置信息 */ pcfg.status = PWM_ENABLE_STATUS; /*运行状态为启用*/
/*设置PWM设备参数*/
ret = PwmSetConfig(handle, &pcfg);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmSetConfig: failed, ret %d\n", ret); /*错误处理*/
} }
``` ```
### 释放PWM设备句柄<a name="section12987111511450"></a> ### 获取PWM设备参数<a name="section3.10_PWM_des"></a>
void PwmClose\(DevHandle handle\); 获取PWM设备参数。
该函数会释放掉由PwmClose申请的资源。 ```c
int32_t PwmGetConfig(DevHandle handle, struct PwmConfig *config);
```
**表 10** PwmClose参数描述 **表11** PwmGetConfig参数描述
<a name="table72517953115"></a> <a name="table11_PWM_des"></a>
<table><tbody><tr id="row1525793312"><td class="cellrowborder" valign="top" width="50%"><p id="p115402031153111"><a name="p115402031153111"></a><a name="p115402031153111"></a><strong id="b691142582513"><a name="b691142582513"></a><a name="b691142582513"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p65406313319"><a name="p65406313319"></a><a name="p65406313319"></a><strong id="b1892414252254"><a name="b1892414252254"></a><a name="b1892414252254"></a>参数描述</strong></p>
</td>
</tr>
<tr id="row1926109193116"><td class="cellrowborder" valign="top" width="50%"><p id="p105419317318"><a name="p105419317318"></a><a name="p105419317318"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="50%"><p id="p16541153110317"><a name="p16541153110317"></a><a name="p16541153110317"></a>PWM设备句柄</p>
</td>
</tr>
</tbody>
</table>
``` | 参数 | 参数描述 |
PwmClose(pwm); /* 释放PWM设备句柄 */ | ---------- | -------------- |
| handle | PWM设备句柄 |
| *config | 参数指针 |
| **返回值** | **返回值描述** |
| 0 | 获取成功 |
| 负数 | 获取失败 |
```c
int32_t ret;
struct PwmConfig pcfg;
/*获取PWM设备参数*/
ret = PwmGetConfig(handle, &pcfg);
if (ret != 0) {
/*错误处理*/
}
``` ```
## 使用实例<a name="section138636719469"></a> ## 使用实例<a name="section4_PWM_des"></a>
PWM设备完整的使用示例如下所示,首先获取PWM设备句柄,然后设置PWM设备配置信息,使能PWM,最后释放PWM设备句柄。 PWM设备完整的使用示例如下所示,首先获取PWM设备句柄,然后设置设备周期、占空时间、极性,获取设备参数。使能,设置设备参数,禁用,最后销毁PWM设备句柄。
``` ```
#include "hdf_log.h"
#include "osal_time.h"
#include "pwm_if.h"
void PwmTestSample(void) void PwmTestSample(void)
{ {
int32_t ret; int32_t ret;
struct PwmConfig config; /* PWM配置信息 */ uint32_t num;
DevHandle pwm = NULL; /* PWM设备句柄 */ DevHandle handle = NULL;
pwm = PwmOpen(0); /* 获取PWM设备句柄 */ struct PwmConfig pcfg;
if (pwm == NULL) { pcfg.duty = 20000000; /*占空时间为20000000纳秒*/
HDF_LOGE("PwmOpen: pwm0 failed"); pcfg.period = 40000000; /*周期为40000000纳秒*/
pcfg.number = 100; /*生成100个方波*/
pcfg.polarity = PWM_NORMAL_POLARITY; /*极性为正*/
pcfg.status = PWM_ENABLE_STATUS; /*运行状态为启用*/
/* PWM设备编号,要填写实际平台上的编号 */
num = 1;
/* 获取PWM设备句柄 */
handle = PwmOpen(num);
if (handle == NULL) {
HDF_LOGE("PwmOpen: failed!\n");
return; return;
} }
/* 获取PWM设备配置信息 */
ret = PwmGetConfig(pwm, &config); /*设置周期为50000000纳秒*/
ret = PwmSetPeriod(handle, 50000000);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmGetConfig: failed, ret %d\n", ret); HDF_LOGE("PwmSetPeriod: failed, ret %d\n", ret);
goto err; goto _ERR;
} }
config.duty = 500; /* 占空比500纳秒 */
config.period = 1000; /* 周期1000纳秒 */ /*设置占空时间为25000000纳秒*/
/* 设置PWM设备配置信息 */ ret = PwmSetDuty(handle, 25000000);
ret = PwmSetConfig(pwm, &config);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmSetConfig: failed, ret %d\n", ret); HDF_LOGE("PwmSetDuty: failed, ret %d\n", ret);
goto err; goto _ERR;
}
/*设置极性为反*/
ret = PwmSetPolarity(handle, PWM_INVERTED_POLARITY);
if (ret != 0) {
HDF_LOGE("PwmSetPolarity: failed, ret %d\n", ret);
goto _ERR;
} }
/* 使能PWM */
ret = PwmEnable(pwm); /*获取PWM设备参数*/
ret = PwmGetConfig(handle, &pcfg);
if (ret != 0) {
HDF_LOGE("PwmGetConfig: failed, ret %d\n", ret);
goto _ERR;
}
/*启用PWM设备*/
ret = PwmEnable(handle);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmEnable: failed, ret %d\n", ret); HDF_LOGE("PwmEnable: failed, ret %d\n", ret);
goto err; goto _ERR;
} }
/* 睡眠10秒 */
OsalSleep(10); /*设置PWM设备参数*/
/* 禁用PWM */ ret = PwmSetConfig(handle, &pcfg);
ret = PwmDisable(pwm); if (ret != 0) {
HDF_LOGE("PwmSetConfig: failed, ret %d\n", ret);
goto _ERR;
}
/*禁用PWM设备*/
ret = PwmDisable(handle);
if (ret != 0) { if (ret != 0) {
HDF_LOGE("PwmDisable: failed, ret %d\n", ret); HDF_LOGE("PwmDisable: failed, ret %d\n", ret);
goto err; goto _ERR;
} }
err:
/* 释放PWM设备句柄 */ _ERR:
PwmClose(pwm); /* 销毁PWM设备句柄 */
PwmClose(handle);
} }
``` ```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册