1,vivado硬件工程并加约束,导入sdk生成*.hdf

ZYNQ7000 petalinux读取AXI_IIC的1302时钟数据

set_property SEVERITY {Warning} [get_drc_checks UCIO-1]

set_property PACKAGE_PIN L15 [get_ports IIC0_scl_io]
set_property PACKAGE_PIN L14 [get_ports IIC0_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC0_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC0_sda_io]

set_property PACKAGE_PIN P20 [get_ports IIC1_scl_io]
set_property PACKAGE_PIN P21 [get_ports IIC1_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC1_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports IIC1_sda_io]

2,petalinux-config --get-hw-description ../linux_base.sdk 导入硬件

ZYNQ7000 petalinux读取AXI_IIC的1302时钟数据

3,添加驱动并编译编译内核

进入driver/rtc下,加入1302驱动drv_ds1302.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/rtc.h>

#define RTC_SET_DATE      0x0c
#define RTC_SET_TIME      0x08

#define RTC_GET_DATE      0x04
#define RTC_GET_TIME      0x00

struct ax_rtc_ds1302_dev {
    struct rtc_device    *rtc;
    void __iomem        *reg_base;
    int                    alarm_irq;
    int                    sec_irq;
    int                 calibval;
};


static int ax_rtc_ds1302_set_time(struct device *dev, struct rtc_time *tm)
{

    struct ax_rtc_ds1302_dev *xrtcdev = dev_get_drvdata(dev);
    u32 utime, udate;

    u32 tempY  = ((tm->tm_year)/10*16+(tm->tm_year)%10)<<16;
    u32 tempM = (tm->tm_mon/10*16+tm->tm_mon%10)<<8;
    u32 tempD = (tm->tm_mday/10*16+tm->tm_mday%10);

    udate = tempY + tempM + tempD + 0x80000000;

    u32 tempH = (tm->tm_hour/10*16+ tm->tm_hour%10)<<16;
    u32 tempI = (tm->tm_min/10*16+tm->tm_min%10)<<8;
    u32 tempS = tm->tm_sec;

    utime = tempH + tempI + tempS;

    writel(udate, xrtcdev->reg_base + RTC_SET_DATE);
    writel(utime, xrtcdev->reg_base + RTC_SET_TIME);

    return 1;
}


static int ax_rtc_ds1302_read_time(struct device *dev, struct rtc_time *tm)
{
    struct ax_rtc_ds1302_dev *xrtcdev = dev_get_drvdata(dev);
    u32 utime = readl(xrtcdev->reg_base + RTC_GET_TIME);
    u32 udate = readl(xrtcdev->reg_base + RTC_GET_DATE);

    u8 temp = (unsigned char)(udate >> 16);
    tm->tm_year = temp/16*10 + temp%16 ;

    temp = (unsigned char)(udate >> 8);
    tm->tm_mon  = temp/16*10 + temp%16;
    temp = (unsigned char)(udate);    
    tm->tm_mday = temp/16*10 + temp%16;;

    temp = (unsigned char)(utime >> 16);
    tm->tm_hour = temp/16*10 + temp%16;
    temp = (unsigned char)(utime >> 8);
    tm->tm_min    = temp/16*10 + temp%16;
    temp = (unsigned char)(utime);        
    tm->tm_sec= temp/16*10 + temp%16;

    if(rtc_valid_tm(tm)<0)
    {
        tm->tm_year     = 117;
        tm->tm_mon      = 11;
        tm->tm_mday     = 10;
        tm->tm_hour     = 13;
        tm->tm_min      = 0;
        tm->tm_sec        = 0;
        ax_rtc_ds1302_set_time(dev,tm);
    }    

    return rtc_valid_tm(tm);
}


static const struct rtc_class_ops ax_rtc_ops =

{
    .set_time             = ax_rtc_ds1302_set_time,
    .read_time            = ax_rtc_ds1302_read_time,
};


static int ax_rtc_ds1302_probe(struct platform_device *pdev)
{
    struct ax_rtc_ds1302_dev     *xrtcdev;
    struct resource     *res;
    int                 ret;
    xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
    if(!xrtcdev)
        return -ENOMEM;

    platform_set_drvdata(pdev, xrtcdev);

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if(res == NULL)
    {
        return -ENOENT;
    }

    xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev,res);
    if(IS_ERR(xrtcdev->reg_base))
    {

        return PTR_ERR(xrtcdev->reg_base);
    }


    device_init_wakeup(&pdev->dev, 1);

    xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
            &ax_rtc_ops, THIS_MODULE);

    return PTR_ERR_OR_ZERO(xrtcdev->rtc);

    
}

 

static int ax_rtc_ds1302_remove(struct platform_device *pdev)
{
    device_init_wakeup(&pdev->dev, 0);
    return 0;
}

static int __maybe_unused ax_rtc_ds1302_suspend(struct device *dev)
{
    struct platform_device *pdev     = to_platform_device(dev);
    struct ax_rtc_ds1302_dev *xrtcdev     = platform_get_drvdata(pdev);


    return 0;
}

static int __maybe_unused ax_rtc_ds1302_resume(struct device *dev)
{
    struct platform_device *pdev     = to_platform_device(dev);
    struct ax_rtc_ds1302_dev *xrtcdev     = platform_get_drvdata(pdev);


    return 0;
}


static SIMPLE_DEV_PM_OPS(ax_rtc_ds1302_pm_ops, ax_rtc_ds1302_suspend, ax_rtc_ds1302_resume);

static const struct of_device_id ax_rtc_ds1302_of_match[] = {
    {.compatible = "alinx,ax-rtc-ds1302" },
    { }
};
MODULE_DEVICE_TABLE(of, ax_rtc_ds1302_of_match);

static struct platform_driver ax_rtc_ds1302_driver = {
    .probe        = ax_rtc_ds1302_probe,
    .remove        = ax_rtc_ds1302_remove,
    .driver        = {
        .name    = KBUILD_MODNAME,
        .pm        = &ax_rtc_ds1302_pm_ops,
        .of_match_table    = ax_rtc_ds1302_of_match,
    },
};

module_platform_driver(ax_rtc_ds1302_driver);

MODULE_DESCRIPTION("Alinx DS1302 RTC driver");
MODULE_AUTHOR("Guowc.");
MODULE_LICENSE("GPL v2");

(2)在driver/rtc下的makefile增加一句

      obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o

(3)在driver/rtc下的kconfig增加一句

    config RTC_DRV_DS1302
    tristate "Dallas/Maxim DS1302"
    depends on SPI
    help
      If you say yes here you get support for the Dallas DS1302 RTC chips.

      This driver can also be built as a module. If so, the module
      will be called rtc-ds1302.

(4)选择对应rtc驱动并保存 petalinux-config -c kernel

Device Driver->Real Time Clock->Alinx DS1302

ZYNQ7000 petalinux读取AXI_IIC的1302时钟数据

ZYNQ7000 petalinux读取AXI_IIC的1302时钟数据

5,修改设备树

        xilinx_drm
        {
            compatible = "xlnx,drm";
            xlnx,vtc = <0x9>;
            xlnx,connector-type = "HDMIA";
            xlnx,encoder-slave = <0xa>;
            clocks = <0xb>;
            dglnt,edid-i2c = <0x8>;
            planes
            {
                xlnx,pixel-format = "xrgb8888";
                plane0
                {
                    dmas = <0xc 0x0>;
                    dma-names = "dma";
                };
            };
        };
        digilent_encoder
        {
            compatible = "dglnt,drm-encoder";
            dglnt,edid-i2c = <0x8>;
            linux,phandle = <0xa>;
            phandle = <0xa>;
        };
        ax_rtc
        {
            compatible = "alinx,ax-rtc-ds1302";
            reg = <0x43C20000 0x1000>;
        };
    };

6,编译petalinux-build,并把启动文件放入sd卡

相关文章:

  • 2021-07-09
  • 2021-09-09
  • 2021-06-28
  • 2022-01-01
  • 2022-12-23
  • 2022-12-23
  • 2021-06-18
猜你喜欢
  • 2021-04-15
  • 2021-04-11
  • 2021-06-02
  • 2021-12-23
  • 2021-12-26
  • 2021-07-28
  • 2021-12-13
相关资源
相似解决方案