2020年7月8日 星期三

ADC-read battery

kernel有留ioctl來讀資料
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <signal.h>

//#define DEBUG_ENV
#ifdef DEBUG_ENV
#define fprintfs(fmt,args...) fprintf(stdout, fmt ,##args)
#define fprintfe(fmt,args...) fprintf(stderr, fmt ,##args)
#define DEBUGMSG __FILE__, __LINE__, __FUNCTION__
#else
#define fprintfs(fmt,args...)
#define fprintfe(fmt,args...)
#endif

#define SARADC_IOC_MAGIC 'a'
#define MS_SAR_INIT _IO(SARADC_IOC_MAGIC, 0)
#define MS_SAR_SET_CHANNEL_READ_VALUE _IO(SARADC_IOC_MAGIC, 1)

int STOP_FLAG=0;
typedef struct
{
    int channel_value;
    int adc_value;
}READ_ADC_t;

int read_saradc (char *argv[], int fd, int *val)
{
    READ_ADC_t radc;
    //sscanf(argv[1], "%d", &radc.channel_value);
    sscanf("3", "%d", &radc.channel_value); //PAD_SAR_GPIO
    if (fd < 0)
    {
        fprintf(stderr, "/dev/saradc");
        return 0; 
    }
    if (ioctl(fd, MS_SAR_SET_CHANNEL_READ_VALUE, &radc)< 0)
    {
        fprintf(stderr, "ioctl failed\n");
        return 0;
    }
    fprintfs("radc_channel=%d\n", radc.channel_value);
    fprintfs("radc_adc_value=%d\n", radc.adc_value);
    *val=radc.adc_value;
    return 1;
}

void sigroutine(int dunno)
{
    switch(dunno){
        case SIGINT:
            fprintfs("ctrl-c signal\n");
            STOP_FLAG=1;
        break;
        case SIGTERM:
            fprintfs("terminal signal\n");
            STOP_FLAG=1;
        break;
        case SIGQUIT:
            fprintfs("quit signal\n");
            STOP_FLAG=1;
        break;
        default:
            fprintfs("Unknow signal\n");
    }
}

unsigned char bat_percent(int val)
{
    int i=0, j=0;
    int bat[16]={644, 628, 616,
                 600, 583, 570, 552, 
                 530, 522, 500, 492, 
                 476, 461, 0};
   
    for(j=0; j<(int)(sizeof(bat)/sizeof(bat[0])); j++)
    {
        if (bat[j] == 0)
            break;
    } 

    for (i=0; i<j; i++)
    {
        if (val >= bat[i])
        {
            break;
        }
    }
    if ( 10-i == -1)
        return 5;
    if ( 10-i == -2 || 10-i == -3)
        return 0;

    return (10-i)*10;
}

void min_max(int *val, int *minval)
{
    static int min=0;
    static int max=0;

    if (min == 0 && max == 0)
    { 
        min=*val;
        *minval=*val;
        max=*val;
    }

    if (*val < min)
    {
        min=*val;
        *minval=min;
    }
    if (*val > max)
        max=*val;
    fprintfs("min=%d, minval=%d, max=%d\n", min, *minval, max);
    return;
}

int main(int argc, char *argv[])
{
    int adc_val=0, get_min_val=0;
    int fd=0;
    int i=0, j=0;
    unsigned char ret=0;
    if(!(fd = open("/dev/saradc", O_RDONLY|O_NONBLOCK)))
        return 0;
    signal(SIGINT , sigroutine);
    signal(SIGQUIT, sigroutine);
    for(i=0;i<10 && !STOP_FLAG;i++)
    {
        read_saradc(argv, fd, &adc_val);
        min_max(&adc_val, &get_min_val);
        for(j=0; j<10; j++)
            usleep(1000*5); //5ms
    }
    ret=bat_percent(get_min_val);
    printf("bat=%d%%\n", ret);
    close(fd);
    return 1;
}

沒有留言:

張貼留言