请选择 进入手机版 | 继续访问电脑版
    查看: 192|回复: 3

    [单片机资料] NUC977之RTC备份寄存器操作详解

    [复制链接]

    签到天数: 414 天

    [LV.9]元老将成

    发表于 2018-9-13 22:29:43 | 显示全部楼层 |阅读模式
    NUC970系列CPU和STM32一样自带RTC备份寄存器,供掉电前保存重要数据使用,容量是16x32bit=64byte

    修改rtc驱动,增加nuc970_rtc_ioctl函数

    struct nuc970_rtc_spr {
        unsigned int num;
        unsigned int value;
    };

    #define RTC_SPR_SET_DATA   0x0801
    #define RTC_SPR_GET_DATA   0x0802

    #define REG_RTC_SPR0    0x40 //RTC备份寄存器地址

    static int nuc970_rtc_ioctl(struct device *dev, unsigned int cmd,
            unsigned long arg)
    {
        struct nuc970_rtc *rtc = dev_get_drvdata(dev);
        struct nuc970_rtc_spr rtc_sprs;
        void __user *uarg = (void __user *) arg;
        int *err;
        unsigned char nums;

        err = check_rtc_spr_access_enable(rtc);

        if (IS_ERR(err))
        {
            return PTR_ERR(err);
        }

        if (copy_from_user(&rtc_sprs, uarg, sizeof(rtc_sprs)))
        {
            return -EFAULT;
        }
        nums = rtc_sprs.num;

        switch (cmd)
        {
            case RTC_SPR_SET_DATA:
                //printk("K: set rtc spr%d, value:%x\n", nums, rtc_sprs.value);
                rtc_reg_write(rtc, REG_RTC_SPR0+nums*4, rtc_sprs.value);
                break;
            case RTC_SPR_GET_DATA:
                rtc_sprs.value = rtc_reg_read(rtc, REG_RTC_SPR0+nums*4);
                //printk("K: get rtc spr%d, value:%x\n", nums, rtc_sprs.value);
                rtc_sprs.num = nums;

                if (copy_to_user(uarg, &rtc_sprs, sizeof(rtc_sprs)))
                {
                    return -EFAULT;
                }

                break;
        }

        return 0;
    }

    static struct rtc_class_ops nuc970_rtc_ops = {
        .ioctl = nuc970_rtc_ioctl,
        .read_time = nuc970_rtc_read_time,
        .set_time = nuc970_rtc_set_time,
        .read_alarm = nuc970_rtc_read_alarm,
        .set_alarm = nuc970_rtc_set_alarm,
        .alarm_irq_enable = nuc970_alarm_irq_enable,
    };

    测试demo

    #include <stdio.h>
    #include <string.h>
    #include <linux/rtc.h>
    #include <sys/ioctl.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <errno.h>
    #include <math.h>
    #include <signal.h>

    struct nuc970_rtc_spr {
        unsigned int num;
        unsigned int value;
    };

    #define RTC_SPR_SET_DATA   0x0801
    #define RTC_SPR_GET_DATA   0x0802

    #define FILE_DEV "/dev/rtc0"
    int main (int argc, char* argv[])
    {
        int i=0;
        int fd = -1;
        int ret = -1;
        struct nuc970_rtc_spr rtc_spr;

        memset(&rtc_spr, 0x00, sizeof(rtc_spr));
        printf("---------------------\n");

        fd = open (FILE_DEV, O_RDWR);
        if (fd < 0)
        {
            printf("### open "FILE_DEV" fail!\n");
            return -1;
        }
        //测试读RTC SPR0寄存器的值
        rtc_spr.num = 0;
        if ((ret = ioctl(fd, RTC_SPR_GET_DATA, &rtc_spr)) < 0)
        {
            printf("### ioctl "FILE_DEV" get rtc spr%d data faile %d\n", rtc_spr.num, ret);
            return ret;
        }

        printf("### read rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value);
        //测试写数据到RTC SPR0寄存器
        rtc_spr.num = 0;
        rtc_spr.value += 0xA5;
        printf("### write rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value);
        if ((ret = ioctl(fd, RTC_SPR_SET_DATA, &rtc_spr)) < 0)
        {
            printf("### ioctl "FILE_DEV" set rtc spr%d data faile %d\n",rtc_spr.num, ret);
            return ret;
        }
        //测试读RTC SPR1寄存器的值
        rtc_spr.num = 1;
        if ((ret = ioctl(fd, RTC_SPR_GET_DATA, &rtc_spr)) < 0)
        {
            printf("### ioctl "FILE_DEV" get rtc spr%d data faile %d\n", rtc_spr.num, ret);
            return ret;
        }
        printf("### read rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value);

        //测试写数据到RTC SPR1寄存器
        rtc_spr.num = 1;
        rtc_spr.value += 0xA6;
        printf("### write rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value);
        if ((ret = ioctl(fd, RTC_SPR_SET_DATA, &rtc_spr)) < 0)
        {
            printf("### ioctl "FILE_DEV" set rtc spr%d data faile %d\n",rtc_spr.num, ret);
            return ret;
        }

        return 0;
    }

    签到天数: 693 天

    [LV.9]元老将成

    发表于 2018-9-14 13:37:41 | 显示全部楼层
    不错的资料
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    返回顶部