/****************************.c*****************************************/
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include #include #include #include #include #include #include #include #include #include #include #include #include #include "fan_control.h"
#define PWM_IOCTL_BASE 'P'
#define PWM_CONFIG _IOW(PWM_IOCTL_BASE, 1 , struct pwm_config)
#define PWM_ENABLE _IOW(PWM_IOCTL_BASE, 2 , int)
#define PWM_DISABLE _IOW(PWM_IOCTL_BASE, 3 , int)
#define GROUP_PWM_CONFIG _IOW(PWM_IOCTL_BASE, 4, struct pwm_config_group)
struct pwm_config {
int pwm_id; //id,0对应pwm0,类推
int duty_ns; //占空比时间,单位ns
int period_ns; //周期时间,单位ns
int pwm_polarity; // 0表示 PWM_POLARITY_NORMAL, 1表示PWM_POLARITY_INVERSED
};
struct pwm_config_group {
int pwm_id[4]; //id,0对应pwm0,类推
int duty_ns; //占空比时间,单位ns
int period_ns; //周期时间,单位ns
int pwm_polarity; // 0表示 PWM_POLARITY_NORMAL, 1表示PWM_POLARITY_INVERSED
int group_channel; //组使用 0表示不使用,1表示使用第零组,2表示使用第一组
int group_run_count; //组脉冲数
};
static int pwmFd = 0;
const int pwmID = 0;
const int periodNs=1000*1000*10; //5ms
static void initPwmFd() {
FILE* fp = fopen("/proc/devices","r");
char *line = NULL;
size_t len = 0;
size_t read = 0;
int major = 0;
if (fp == NULL) return;
while ( (read = getline(&line,&len, fp)) != -1) { //line是字符指针,read是读取的字节数
char *x = strstr(line, "sunxi-pwm-dev"); //返回"sunxi-pwm-dev"在line的位置指针
if (x!=NULL) {
char *numStr = calloc(sizeof(char), 64);
strncpy(numStr,line,x-line-1); //拷贝主设备号
major = atoi(numStr);
free(numStr);
break;
}
}
fclose(fp);
if (line)
free(line);
if (major <= 0) {
printf("error find pwm node\n");
return;
}
dev_t devT = makedev(major,0);
if (mknod("/dev/fan", S_IFCHR | 0660, makedev(major, 0))) {
if (errno != EEXIST) {
printf("error mknod %d\n",errno);
}
}
if (pwmFd<=0)
pwmFd = open("/dev/fan",O_RDWR | O_CLOEXEC);
if (pwmFd <=0) {
printf("open /dev/fan fail!\n");
}
}
int enableFan(int percent) {
int ret = 0;
struct pwm_config config = {pwmID, 0, periodNs, 0, 0, 0};
if (percent < 0 ) percent = 0;
if (percent > 100 ) percent = 100;
printf("enable fan %d%\n",percent);
initPwmFd();
if (pwmFd<=0) {
printf("ioctl fd open fail %d \n",errno);
return -1;
}
if (percent == 0) {
//ret = ioctl(pwmFd, PWM_CONFIG, &config);
//printf("config ret %d\n",ret);
//if (ret<0) return ret;
//return ioctl(pwmFd, PWM_ENABLE, pwmID);
}
int dutyNs = percent * (periodNs/100);
dutyNs = dutyNs>periodNs?periodNs:dutyNs;
config.duty_ns=dutyNs;
ret = ioctl(pwmFd, PWM_CONFIG, &config);
if (ret<0) return ret;
ioctl(pwmFd, PWM_ENABLE, pwmID);
return ret;
}
int enableMotor(int period_ns, int run_count, int polarity) {
int ret = 0;
struct pwm_config_group config = {{0, 1, 2, 3}, 0, periodNs, 0, 1, 0};
initPwmFd();
if (pwmFd<=0) {
printf("ioctl fd open fail %d \n",errno);
return -1;
}
if (period_ns < 10) {
printf("the first number less than 10ns \n");
return -1;
}
config.period_ns = period_ns;
config.duty_ns = period_ns*3/8;
config.pwm_polarity = polarity;
config.group_channel = 1;
config.group_run_count = run_count;
ret = ioctl(pwmFd, GROUP_PWM_CONFIG, &config);
if (ret<0) return ret;
// ioctl(pwmFd, PWM_ENABLE, pwmID);
return ret;
}
/*****************************.h**************************/
#ifndef FAN_CONTROL_H
#define FAN_CONTROL_H
#ifdef __cplusplus
extern "C" {
#endif
int enableFan(int percent);
int enableMotor(int period_ns, int run_count, int polarity);
#ifdef __cplusplus
}
#endif
#endif
/***************************main*************************/
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include #include #include #include #include #include #include "fan_control.h"
void printHelp(const char * cmd) {
printf("\n");
printf("usage:\n");
printf("%s [percent]\n",cmd);
printf("[percent] : 0 ~ 100\n");
}
int main(int argc, char** argv) {
#if 0
if (argc != 2) {
printHelp(*argv);
return -1;
}
enableFan(atoi(*(argv+1)));
#endif
#if 1
if (argc != 4) {
printHelp(*argv);
return -1;
}
// enableFan(atoi(*(argv+1)));
enableMotor(atoi(*(argv+1)),atoi(*(argv+2)),atoi(*(argv+3)));
#endif
return 0;
}