Olimex Support Forum

OLinuXino Android / Linux boards and System On Modules => A20 => Topic started by: felipegn on May 22, 2014, 11:59:33 PM

Title: Adafruit's RTC
Post by: felipegn on May 22, 2014, 11:59:33 PM
Hello.

I would like to know if someone has tested the Adafruit's RTC in A20-OlinuXino-MICRO.

It detects the RTC (in i2c-0 in address 0x68) but i can't collect the date from it.
hwclock -r -f /dev/rtc0 gives me "select() to /dev/rtc0 to wait for clock tick timed out: Success" but it doesn't show the date.

Can someone help me?

Thank you.
Title: Re: Adafruit's RTC
Post by: bubi on May 23, 2014, 12:39:41 AM
Hello felipegn,
I bought the same chip (DS1307) yesterday, but I'm accessing to it directly using the i2c-tools (http://linux-sunxi.org/I2Cdev, some documentation here http://www.lm-sensors.org/wiki/i2cToolsDocumentation).
With this tool it works (you only need to know the RTC internal addresses, see the datasheet http://datasheets.maximintegrated.com/en/ds/DS1307.pdf).

Just a question, what voltage are you providing to the chip? DS1307 runs at 5V, at 3.3V it doesn't work properly. I also use a level shifter to interface it with the olinuxino.

Regards 
Title: Re: Adafruit's RTC
Post by: felipegn on May 23, 2014, 12:54:36 AM
Hello bubi, thanks for your response.

I will try to use this documentation you posted

I'm using 5 V to power the chip without resistors (so the i2c voltage level is 3.3 V).

Regards
Title: Re: Adafruit's RTC
Post by: dave-at-axon on May 23, 2014, 05:41:26 AM
I don't use the DS1307 but instead use the DS1338 which is 3.3V powered and is pin and software compatible.

Which OS are you using?

I am running Android and I had to build the Android Linux kernel to support the RTC and make sure I included the initialisation for it as I2C devices are not automatically probed.

Although the DC characteristics for the DS1307 show a high as 2.2V I've often found that trying to get 5V devices running on 5V power to work with 3.3V inputs and outputs can be troublesome. Better if you can add a level shifter. I saw this very recently with an RS485 bus device. The device was 5V powered and I tried to send data. I got garbage. Added the level shifter and I now have clean data.
Title: Re: Adafruit's RTC
Post by: herter on May 23, 2014, 10:23:12 AM
Hello,

In addition of this voltage issue, did you connect the resistors named Rpu in the datasheet?
Moreover can you visualize the SDA signal with a scope for instance?
Title: Re: Adafruit's RTC
Post by: bubi on May 23, 2014, 11:11:16 AM
Hi,

the pull-up resistors (Rpu) for the i2c are already present in the olinuxino, since they are also present in the adafruit rtc breakout (that is working at 5V) a conflict may occur.
I suggest you to remove the pull-up from the adafruit breakout and use a level shifter for avoid any damage to the olinuxino pins (that are NOT 5V tolerant)

Regards
Title: Re: Adafruit's RTC
Post by: herter on May 23, 2014, 03:20:35 PM
Yes, I know, that's why I would like to know if the Rpu have been removed.
Title: Re: Adafruit's RTC
Post by: bubi on May 23, 2014, 04:20:46 PM
I didn't understand that we meant the same thing, sorry
Title: Re: Adafruit's RTC
Post by: felipegn on May 26, 2014, 10:36:24 PM
Hello guys.

- I use Debian as OS
- I removed both resistors from Adafruit's RTC

I connect the olinuxino's pins to rtc's pins, and then I run the modified MOD-RTC's example.
I had to change the adress, the start buffer, etc... because it changes from one rtc to another.

It's strange because I get the correct hour, minute and second, but when it comes to month day, week day and year it's wrong. Besides, it gets delayed very fast from the current time.

Sometimes I wonder if the i2c gets the clock of the processor or somewhere else.

Thank you for your responses.
Title: Re: Adafruit's RTC
Post by: ylsantos on May 26, 2014, 11:38:30 PM
I am trying to make it work too, but with no success. I am using Debian as OS (the 5th image if I am not mistaken) and a different approach than yours.

First I tried to follow Adafruit's recommendations to raspberry pi with eventual modifications. It didn't work.

Then I started to look for drivers or something related to that. Besides, I looked for the config file of the system (which was supposed to be in /boot, wasn't it?). The /boot directory is empty, and I made a deep research for files with 'config', 'debconfig', 'defconfig' and other terms in their names. But I didn't find anything. Does anyone know where the configuration file is?

This file contains every function that is enabled or not. My intention is to see if the RTC lines are ok. It is something like that: CONFIG_RTC=y. And maybe enable the RTC DS1307 driver in this file (same structure than CONFIG).

As an example, I am posting below some parts of the config file of my server (Ubuntu).

/boot/config-3.2.0-48-generic

CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
CONFIG_RTC_DRV_88PM860X=m
CONFIG_RTC_DRV_DS1307=m
CONFIG_RTC_DRV_DS1374=m
CONFIG_RTC_DRV_DS1672=m
CONFIG_RTC_DRV_DS3232=m
CONFIG_RTC_DRV_MAX6900=m
CONFIG_RTC_DRV_MAX8925=m
CONFIG_RTC_DRV_MAX8998=m
CONFIG_RTC_DRV_RS5C372=m
CONFIG_RTC_DRV_ISL1208=m
CONFIG_RTC_DRV_ISL12022=m
CONFIG_RTC_DRV_X1205=m
CONFIG_RTC_DRV_PCF8563=m
CONFIG_RTC_DRV_PCF8583=m
CONFIG_RTC_DRV_M41T80=m
CONFIG_RTC_DRV_M41T80_WDT=y
CONFIG_RTC_DRV_BQ32K=m
CONFIG_RTC_DRV_S35390A=m
CONFIG_RTC_DRV_FM3130=m
CONFIG_RTC_DRV_RX8581=m
CONFIG_RTC_DRV_RX8025=m
CONFIG_RTC_DRV_EM3027=m
CONFIG_RTC_DRV_RV3029C2=m

Is my reasoning correct?
Title: Re: Adafruit's RTC
Post by: dave-at-axon on May 27, 2014, 06:30:35 AM
I wonder if this information would help you get it working? Assuming you are building your own kernel.

I used the DS1338 which is a 3.3V and more accurate and code compatible version of the DS1307. The DS1307 drifts like hell with temperature changes. I've found the DS1338 to be a lot more accurate in time keeping. I still sync to an external time server if there is an internet connection just to keep it more accurate. :)

https://axonjakarta.wordpress.com/2014/03/31/external-battery-backed-real-time-clock-rtc-for-a20-with-android/

This is for Android Linux but it should be the same for any linux as I2C devices are not probed so you need to add them so that the kernel knows about them.

With this I now have a battery backed real time clock on the A20.
Title: Re: Adafruit's RTC
Post by: bubi on May 28, 2014, 05:54:46 PM
Hi,

I tryed the tutorial by adafruit for the raspberry and it works:
https://learn.adafruit.com/adding-a-real-time-clock-to-raspberry-pi/set-rtc-time

But I want the RTC is registered at boot-up

@dave-at-axon

I'm trying to follow what you suggest to do. I also found some documentation (https://www.kernel.org/doc/Documentation/i2c/instantiating-devices) and a tutorial for raspberry (http://microeletroniki.wordpress.com/2012/09/05/ds1307-with-rpi-kernel-on-bootup/)

But I'm still trying to understand what file I have to modify for the A20 (I'm on debian, kernel 3.4.79)

Under arch/arm/mach-sun7i there isn't a file containing info about board (just a core.h).
In arch/arm/plat-sunxi there is a core.c that's seems to be the right file, but it doesn't contain any i2c setup.

I'm googling to find a solution but with no result...

Thanks in advance for any suggestions

Regards
Title: Re: Adafruit's RTC
Post by: dave-at-axon on May 29, 2014, 05:02:34 AM
Yeah, I found that the sunxi kernel uses a different naming convention to other kernels. The touch screen I added references a boardxxxx.c file and I could not find it. The core.c file was the only one that I found that had the init code I was looking for. I don't have the Debian source so can't comment on the internals but with my core.c file there was no I2C in there to begin with.

The file layout structure is probably different but it sounds like you found the right core.c file.

If it has the following at the bottom or very similar, this is the place to put the I2C header and init calls.


ACHINE_START(SUN7I, "sun7i")
.atag_offset = 0x100,
.fixup = sun7i_fixup,
.reserve        = sun7i_reserve,
.map_io = sun7i_map_io,
.init_early = sun7i_init_early,
.init_irq = gic_init_irq,
.timer = &sun7i_timer,
.handle_irq = gic_handle_irq,
.init_machine = sun7i_init,
#ifdef CONFIG_ZONE_DMA
.dma_zone_size = SZ_256M,
#endif
.restart = sun7i_restart,
MACHINE_END


It should also have a function similar to void __init sun7i_init_early(void)

If not sure, post it here or try as an attachment and I can have a quick look.
Title: Re: Adafruit's RTC
Post by: ylsantos on May 29, 2014, 06:24:55 PM
Hi guys, thanks for your support.

@bubi
I tried the tutorial too. It worked, but not everything went well. For instance, I got an error message when modprobe rtc-ds1307, indicating that this device is unknown, even declaring it as the tutorial says. Besides, it stops working when the board is powered off and then up again (the information is lost). And I believe that the hwclock is not DS1307, because I am using RTC with the function MOD_RTC and the times of both are different. hwclock is showing a big delay too...

@dave-at-axon and @bubi
I didn't find the config file neither. Nor the core.c. There is not a directory /arch or /arm here...

If I want to syncronize the time from RTC since boot, the only way is to rebuild the kernel or can I modify a file to do it? When there is no Internet connection, the system starts at 00:00:00 of 01/01/2010. Changing it to RTC's data may solve the problem. Is that possible?

Thanks!!
Title: Re: Adafruit's RTC
Post by: dave-at-axon on May 29, 2014, 06:47:55 PM
Can you drop a link here where I can find the Debian source and I'll have a dig around it. Sorry, I work with Android so more familiar with that.
Title: Re: Adafruit's RTC
Post by: bubi on May 29, 2014, 07:10:25 PM
Hi,

@ylsantos
I forgot to say that I recompiled the kernel adding the support for DS1307 (under device driver -> rtc)
I added it at boot-up, instead load it as a module. So adding
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
in my /etc/rc.local works well for me (I've just the problem that the time is given in 12h AM/PM instead of 24h)

syncronize the time from RTC since boot is exactly the same thing that I want to do too, but I also want to register the DS1307 at boot-up, not during the execution of rc.local

the file arch/arm/plat-sunxi/core.c is present under the directory ../linux-sunxi which contains all the source file of the kernel (if you want to recompile the kernel, you can follow the guide by olimex as I did http://olimex.wordpress.com/2013/11/05/building-the-ultimate-debian-sd-card-for-linux-with-kernel-3-4-for-a20-olinuxino-micro/)

@dave-at-axon
the core.c that I found contain the MACHINE_START(SUN7I, "sun7i") in the last line, but it doesn't contain a function similar to void __init sun7i_init_early(void)

following the code

/*
* (C) Copyright 2007-2012
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
* Benn Huang <benn@allwinnertech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/amba/pl061.h>
#include <linux/amba/mmci.h>
#include <linux/amba/pl022.h>
#include <linux/io.h>
#include <linux/gfp.h>
#include <linux/clockchips.h>
#include <linux/memblock.h>
#include <linux/bootmem.h>
#include <linux/export.h>
#include <linux/clkdev.h>

#include <asm/arch_timer.h>
#include <asm/sched_clock.h>
#include <asm/setup.h>
#include <asm/sizes.h>
#include <asm/mach-types.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/delay.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/hardware/arm_timer.h>
#include <asm/hardware/gic.h>
#include <asm/hardware/icst.h>
#include <asm/hardware/vic.h>

#include <plat/core.h>
#include <plat/hardware.h>
#include <plat/memory.h>
#include <plat/platform.h>
#include <plat/system.h>
#include <plat/sys_config.h>

#include "clocksrc.h"

int arch_timer_common_register(void);
void sw_pdev_init(void);

/*
* Only reserve certain important memory blocks if there are actually
* drivers which use them.
*/
static unsigned long reserved_start;
static unsigned long reserved_max;

/**
* Machine Implementations
*
*/

/* sun4i / sun5i io-map */
static struct map_desc sw_io_desc[] __initdata = {
{ SW_VA_SRAM_BASE, __phys_to_pfn(SW_PA_SRAM_BASE),  (SZ_128K + SZ_64K), MT_MEMORY_ITCM  },
{ SW_VA_IO_BASE,   __phys_to_pfn(SW_PA_IO_BASE),    (SZ_1M + SZ_2M),    MT_DEVICE       },
{ SW_VA_BROM_BASE, __phys_to_pfn(SW_PA_BROM_BASE),  (SZ_64K),           MT_MEMORY_ITCM  },
};
static void __init sw_core_map_io(void)
{
iotable_init(sw_io_desc, ARRAY_SIZE(sw_io_desc));

sunxi_pr_chip_id();
}

/* sun7i io-map */
static struct map_desc sun7i_io_desc[] __initdata = {
{IO_ADDRESS(SW_PA_IO_BASE), __phys_to_pfn(SW_PA_IO_BASE),  SW_IO_SIZE, MT_DEVICE_NONSHARED},
{IO_ADDRESS(SW_PA_SRAM_A1_BASE), __phys_to_pfn(SW_PA_SRAM_A1_BASE),  SW_SRAM_A1_SIZE, MT_MEMORY_ITCM},
{IO_ADDRESS(SW_PA_SRAM_A2_BASE), __phys_to_pfn(SW_PA_SRAM_A2_BASE),  SW_SRAM_A2_SIZE, MT_MEMORY_ITCM},
{IO_ADDRESS(SW_PA_SRAM_A3_BASE), __phys_to_pfn(SW_PA_SRAM_A3_BASE),  SW_SRAM_A3_SIZE + SW_SRAM_A4_SIZE, MT_MEMORY_ITCM},
//{IO_ADDRESS(SW_PA_SRAM_A4_BASE), __phys_to_pfn(SW_PA_SRAM_A4_BASE),  SW_SRAM_A4_SIZE, MT_MEMORY_ITCM}, /* not page align, cause sun7i_map_io err,2013-1-10 */
{IO_ADDRESS(SW_PA_BROM_START), __phys_to_pfn(SW_PA_BROM_START), SW_BROM_SIZE, MT_DEVICE_NONSHARED},
};
static void __init sun7i_map_io(void)
{
iotable_init(sun7i_io_desc, ARRAY_SIZE(sun7i_io_desc));
sunxi_pr_chip_id();
}

#ifdef CONFIG_FB_SUNXI_RESERVED_MEM
/* The FB block is used by:
*
* - the sun4i framebuffer driver, drivers/video/sun4i/disp.
*
* fb_start, fb_size are used in a vast number of other places but for
* for platform-specific drivers, so we don't have to worry about them.
*/

unsigned long fb_start;
unsigned long fb_size = SZ_32M;
EXPORT_SYMBOL(fb_start);
EXPORT_SYMBOL(fb_size);

static int __init reserve_fb_param(char *s)
{
unsigned long size;
if (kstrtoul(s, 0, &size) == 0)
fb_size = size * SZ_1M;
return 0;
}
early_param("sunxi_fb_mem_reserve", reserve_fb_param);
#endif

#if IS_ENABLED(CONFIG_SUNXI_G2D)
/* The G2D block is used by:
*
* - the G2D engine, drivers/char/sunxi_g2d
*/

unsigned long g2d_start;
unsigned long g2d_size = SZ_1M * 16;
EXPORT_SYMBOL(g2d_start);
EXPORT_SYMBOL(g2d_size);

static int __init reserve_g2d_param(char *s)
{
unsigned long size;
if (kstrtoul(s, 0, &size) == 0)
g2d_size = size * SZ_1M;
return 0;
}
early_param("sunxi_g2d_mem_reserve", reserve_g2d_param);
#endif

#if defined CONFIG_VIDEO_DECODER_SUNXI || \
defined CONFIG_VIDEO_DECODER_SUNXI_MODULE
/* The VE block is used by:
*
* - the Cedar video engine, drivers/media/video/sunxi
*/

#define RESERVE_VE_MEM 1

unsigned long ve_start;
unsigned long ve_size = (SZ_64M + SZ_16M);
EXPORT_SYMBOL(ve_start);
EXPORT_SYMBOL(ve_size);

static int __init reserve_ve_param(char *s)
{
unsigned long size;
if (kstrtoul(s, 0, &size) == 0)
ve_size = size * SZ_1M;
return 0;
}
early_param("sunxi_ve_mem_reserve", reserve_ve_param);
#endif

static void reserve_sys(void)
{
memblock_reserve(SYS_CONFIG_MEMBASE, SYS_CONFIG_MEMSIZE);
pr_reserve_info("SYS ", SYS_CONFIG_MEMBASE, SYS_CONFIG_MEMSIZE);
}

#if defined RESERVE_VE_MEM || defined CONFIG_FB_SUNXI_RESERVED_MEM || \
IS_ENABLED(CONFIG_SUNXI_G2D)
static void reserve_mem(unsigned long *start, unsigned long *size,
const char *desc)
{
if (*size == 0) {
*start = 0;
return;
}

if ((reserved_start + *size) > reserved_max) {
pr_warn("Not enough memory to reserve memory for %s\n", desc);
*start = 0;
*size = 0;
return;
}
*start = reserved_start;
memblock_reserve(*start, *size);
pr_reserve_info(desc, *start, *size);
reserved_start += *size;
}
#endif

static void __init sw_core_reserve(void)
{
pr_info("Memory Reserved:\n");
reserve_sys();
/* 0 - 64M is used by reserve_sys */
#ifdef CONFIG_CMA
/* We want CMA area to be in the first 256MB of RAM (for Cedar),
* so move other reservations above
*/
reserved_start = meminfo.bank[0].start + SZ_256M;
#else
reserved_start = meminfo.bank[0].start + SZ_64M;
#endif
reserved_max   = meminfo.bank[0].start + meminfo.bank[0].size;
#if !defined(CONFIG_CMA) && defined(RESERVE_VE_MEM)
reserve_mem(&ve_start, &ve_size, "VE  ");
#endif
#if IS_ENABLED(CONFIG_SUNXI_G2D)
reserve_mem(&g2d_start, &g2d_size, "G2D ");
#endif
#ifdef CONFIG_FB_SUNXI_RESERVED_MEM
reserve_mem(&fb_start, &fb_size, "LCD ");
#endif
/* Ensure this is set before any arch_init funcs call script_foo */
sunxi_script_init((void *)__va(SYS_CONFIG_MEMBASE));
}

void sw_irq_ack(struct irq_data *irqd)
{
unsigned int irq = irqd->irq;

if (irq < 32){
writel(readl(SW_INT_ENABLE_REG0) & ~(1<<irq), SW_INT_ENABLE_REG0);
writel(readl(SW_INT_MASK_REG0) | (1 << irq), SW_INT_MASK_REG0);
writel(readl(SW_INT_IRQ_PENDING_REG0) | (1<<irq), SW_INT_IRQ_PENDING_REG0);
} else if(irq < 64){
irq -= 32;
writel(readl(SW_INT_ENABLE_REG1) & ~(1<<irq), SW_INT_ENABLE_REG1);
writel(readl(SW_INT_MASK_REG1) | (1 << irq), SW_INT_MASK_REG1);
writel(readl(SW_INT_IRQ_PENDING_REG1) | (1<<irq), SW_INT_IRQ_PENDING_REG1);
} else if(irq < 96){
irq -= 64;
writel(readl(SW_INT_ENABLE_REG2) & ~(1<<irq), SW_INT_ENABLE_REG2);
writel(readl(SW_INT_MASK_REG2) | (1 << irq), SW_INT_MASK_REG2);
writel(readl(SW_INT_IRQ_PENDING_REG2) | (1<<irq), SW_INT_IRQ_PENDING_REG2);
}
}

/* Mask an IRQ line, which means disabling the IRQ line */
static void sw_irq_mask(struct irq_data *irqd)
{
unsigned int irq = irqd->irq;

if(irq < 32){
writel(readl(SW_INT_ENABLE_REG0) & ~(1<<irq), SW_INT_ENABLE_REG0);
writel(readl(SW_INT_MASK_REG0) | (1 << irq), SW_INT_MASK_REG0);
} else if(irq < 64){
irq -= 32;
writel(readl(SW_INT_ENABLE_REG1) & ~(1<<irq), SW_INT_ENABLE_REG1);
writel(readl(SW_INT_MASK_REG1) | (1 << irq), SW_INT_MASK_REG1);
} else if(irq < 96){
irq -= 64;
writel(readl(SW_INT_ENABLE_REG2) & ~(1<<irq), SW_INT_ENABLE_REG2);
writel(readl(SW_INT_MASK_REG2) | (1 << irq), SW_INT_MASK_REG2);
}
}

static void sw_irq_unmask(struct irq_data *irqd)
{
unsigned int irq = irqd->irq;

if(irq < 32){
writel(readl(SW_INT_ENABLE_REG0) | (1<<irq), SW_INT_ENABLE_REG0);
writel(readl(SW_INT_MASK_REG0) & ~(1 << irq), SW_INT_MASK_REG0);
if(irq == SW_INT_IRQNO_ENMI) /* must clear pending bit when enabled */
writel((1 << SW_INT_IRQNO_ENMI), SW_INT_IRQ_PENDING_REG0);
} else if(irq < 64){
irq -= 32;
writel(readl(SW_INT_ENABLE_REG1) | (1<<irq), SW_INT_ENABLE_REG1);
writel(readl(SW_INT_MASK_REG1) & ~(1 << irq), SW_INT_MASK_REG1);
} else if(irq < 96){
irq -= 64;
writel(readl(SW_INT_ENABLE_REG2) | (1<<irq), SW_INT_ENABLE_REG2);
writel(readl(SW_INT_MASK_REG2) & ~(1 << irq), SW_INT_MASK_REG2);
}
}

static struct irq_chip sw_vic_chip = {
.name       = "sw_vic",
.irq_ack    = sw_irq_ack,
.irq_mask   = sw_irq_mask,
.irq_unmask = sw_irq_unmask,
};

void __init sw_core_init_irq(void)
{
u32 i = 0;

/* Disable & clear all interrupts */
writel(0, SW_INT_ENABLE_REG0);
writel(0, SW_INT_ENABLE_REG1);
writel(0, SW_INT_ENABLE_REG2);

writel(0xffffffff, SW_INT_MASK_REG0);
writel(0xffffffff, SW_INT_MASK_REG1);
writel(0xffffffff, SW_INT_MASK_REG2);

writel(0xffffffff, SW_INT_IRQ_PENDING_REG0);
writel(0xffffffff, SW_INT_IRQ_PENDING_REG1);
writel(0xffffffff, SW_INT_IRQ_PENDING_REG2);
writel(0xffffffff, SW_INT_FIQ_PENDING_REG0);
writel(0xffffffff, SW_INT_FIQ_PENDING_REG1);
writel(0xffffffff, SW_INT_FIQ_PENDING_REG2);

/*enable protection mode*/
writel(0x01, SW_INT_PROTECTION_REG);
/*config the external interrupt source type*/
writel(0x00, SW_INT_NMI_CTRL_REG);

for (i = SW_INT_START; i < SW_INT_END; i++) {
irq_set_chip(i, &sw_vic_chip);
irq_set_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}

static void __init gic_init_irq(void)
{
/*
* HdG: note to anyone trying to make it possible to build a single sunxi image
* for all of sun4i/sun5i/sun7i, selecting CONFIG_ARM_GIC automatically selects
* CONFIG_MULTI_IRQ_HANDLER, at which point we need to provide a handle_irq
* function for the sun4i and sun5i machine definitions, vic_handle_irq is
* probably a good start for this / maybe we can even use all of the common
* vic handling code?
*/
#ifdef CONFIG_ARM_GIC
gic_init(0, 29, (void *)IO_ADDRESS(AW_GIC_DIST_BASE),
(void *)IO_ADDRESS(AW_GIC_CPU_BASE));
#endif
}


/*
* Global vars definitions
*
*/
static void sun4i_restart(char mode, const char *cmd)
{
/* use watch-dog to reset system */
#define WATCH_DOG_CTRL_REG  (SW_VA_TIMERC_IO_BASE + 0x0090)
#define WATCH_DOG_MODE_REG  (SW_VA_TIMERC_IO_BASE + 0x0094)

*(volatile unsigned int *)WATCH_DOG_MODE_REG = 0;
__delay(100000);
*(volatile unsigned int *)WATCH_DOG_MODE_REG |= 2;
while(1) {
__delay(100);
*(volatile unsigned int *)WATCH_DOG_MODE_REG |= 1;
}
}

static void __init sw_timer_init(void)
{
aw_clkevt_init();
aw_clksrc_init();
#ifdef CONFIG_ARM_ARCH_TIMER
if (sunxi_is_sun7i()) {
arch_timer_common_register();
arch_timer_sched_clock_init();
} else
#endif
setup_sched_clock(aw_sched_clock_read, 32, AW_HPET_CLOCK_SOURCE_HZ);
}

struct sys_timer sw_sys_timer = {
.init = sw_timer_init,
};

void __init sw_core_init(void)
{
sw_pdev_init();
}

MACHINE_START(SUN4I, "sun4i")
.atag_offset = 0x100,
.timer          = &sw_sys_timer,
.map_io         = sw_core_map_io,
.init_early     = NULL,
.init_irq       = sw_core_init_irq,
.init_machine   = sw_core_init,
.reserve        = sw_core_reserve,
.restart = sun4i_restart,
#ifdef CONFIG_ZONE_DMA
.dma_zone_size = SZ_256M,
#endif
MACHINE_END

MACHINE_START(SUN5I, "sun5i")
.atag_offset = 0x100,
.timer          = &sw_sys_timer,
.map_io         = sw_core_map_io,
.init_early     = NULL,
.init_irq       = sw_core_init_irq,
.init_machine   = sw_core_init,
.reserve        = sw_core_reserve,
.restart = sun4i_restart,
#ifdef CONFIG_ZONE_DMA
.dma_zone_size = SZ_256M,
#endif
MACHINE_END

MACHINE_START(SUN7I, "sun7i")
.atag_offset = 0x100,
.timer          = &sw_sys_timer,
.map_io         = sun7i_map_io,
.init_early     = NULL,
.init_irq = gic_init_irq,
.init_machine   = sw_core_init,
.reserve        = sw_core_reserve,
.restart = sun4i_restart,
#ifdef CONFIG_MULTI_IRQ_HANDLER
.handle_irq = gic_handle_irq,
#endif
#ifdef CONFIG_ZONE_DMA
.dma_zone_size = SZ_256M,
#endif
MACHINE_END



Maybe can I add the DS1307 registration function in void __init sw_core_init(void)?

Thank you very much!
Title: Re: Adafruit's RTC
Post by: felipegn on May 29, 2014, 08:11:21 PM
Hello guys. Thanks for your answers.

I'm still having some issues. I use the following version of Debian Wheezy.
Distributor ID: Debian
Description:    Debian GNU/Linux 7.4 (wheezy)
Release:        7.4
Codename:       wheezy


Do you think the problem could be my version of Debian? When I use the command "modprobe rtc-ds1307"m I get
FATAL: Module rtc-ds1307 not found.

Seems like rtc0 is not recognized as ds1307. I get the same problem as you @ylsantos.

Thank you again.
Title: Re: Adafruit's RTC
Post by: felipegn on May 29, 2014, 08:22:32 PM
I forgot to add one thing:

[    0.000000] Linux version 3.4.67+ (root@debian)
Title: Re: Adafruit's RTC
Post by: bubi on May 29, 2014, 11:52:50 PM
Hi felipegn,

you got that error because, by default, the kernel module for the ds1307 is not present in the kernel configuration.
To make it works you must recompile the kernel adding the support for the ds1307 and removing the sunxi rtc driver.
Follow the olimex's instruction on how recompile the kernel.

Title: Re: Adafruit's RTC
Post by: dave-at-axon on May 30, 2014, 06:28:42 AM
Quote from: bubi on May 29, 2014, 07:10:25 PM
@dave-at-axon
the core.c that I found contain the MACHINE_START(SUN7I, "sun7i") in the last line, but it doesn't contain a function similar to void __init sun7i_init_early(void)

following the code

/*
void __init sw_core_init(void)
{
sw_pdev_init();
}
[/quote]

That's the one. I have sw_pdev_init() in that function too. I placed the i2i_register_board_info after that function.

Hope this helps?
Title: Re: Adafruit's RTC
Post by: bubi on May 30, 2014, 10:53:43 AM
Thank you very much dave-at-axon!

I will try next week (I'm going out for a long weekend  :D)
Title: Re: Adafruit's RTC
Post by: bubi on June 04, 2014, 08:08:56 PM
here I am!

I succesfully compiled the kernel with the ds1307 registration, and now it works from boot-up!
I modified the ../linux-sunxi/arch/arm/plat-sunxi/core.c as follows

static struct i2c_board_info __initdata sun7i_i2c_devices[] = {
        {
                I2C_BOARD_INFO("rtc-ds1307", 0x68),.type = "ds1307",
        },
};


void __init sw_core_init(void)
{
sw_pdev_init();
i2c_register_board_info(1,sun7i_i2c_devices,ARRAY_SIZE(sun7i_i2c_devices));
}


note that in function i2c_register_board_info() the first argument is '1' because I add the ds1307 on the i2c-1 port.

Hope this it's helpful

thanks again dave-at-axon

regards
Title: Re: Adafruit's RTC
Post by: dave-at-axon on June 05, 2014, 05:33:37 AM
Cool.

Glad to have been able to help.