forked from Imagelibrary/rtems
beagle bsp: RTC support for BBB
This commit is contained in:
@@ -114,6 +114,9 @@ libbsp_a_SOURCES += ../../shared/console.c \
|
|||||||
# I2C
|
# I2C
|
||||||
libbsp_a_SOURCES += misc/i2c.c
|
libbsp_a_SOURCES += misc/i2c.c
|
||||||
|
|
||||||
|
#RTC
|
||||||
|
libbsp_a_SOURCES += rtc.c
|
||||||
|
libbsp_a_SOURCES += ../../shared/tod.c
|
||||||
# Clock
|
# Clock
|
||||||
libbsp_a_SOURCES += clock.c
|
libbsp_a_SOURCES += clock.c
|
||||||
libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
|
libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ RTEMS_BSPOPTS_HELP([CONSOLE_BAUD],[initial baud for console UART])
|
|||||||
RTEMS_BSPOPTS_SET([CONSOLE_POLLED],[*],[0])
|
RTEMS_BSPOPTS_SET([CONSOLE_POLLED],[*],[0])
|
||||||
RTEMS_BSPOPTS_HELP([CONSOLE_POLLED],[polled console i/o (e.g. to run testsuite)])
|
RTEMS_BSPOPTS_HELP([CONSOLE_POLLED],[polled console i/o (e.g. to run testsuite)])
|
||||||
|
|
||||||
|
RTEMS_BSPOPTS_SET([BBB_DEBUG],[beaglebone*],[0])
|
||||||
|
RTEMS_BSPOPTS_HELP([BBB_DEBUG],[Enable BBB debug])
|
||||||
|
|
||||||
RTEMS_BSP_CLEANUP_OPTIONS(0, 0)
|
RTEMS_BSP_CLEANUP_OPTIONS(0, 0)
|
||||||
RTEMS_BSP_LINKCMDS
|
RTEMS_BSP_LINKCMDS
|
||||||
|
|
||||||
|
|||||||
277
c/src/lib/libbsp/arm/beagle/rtc.c
Normal file
277
c/src/lib/libbsp/arm/beagle/rtc.c
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup arm_beagle
|
||||||
|
*
|
||||||
|
* @brief RTC driver for AM335x SoC.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Ragunath <ragunath3252@gmail.com>.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bspopts.h>
|
||||||
|
|
||||||
|
#if IS_AM335X
|
||||||
|
#include <rtems.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <libchip/rtc.h>
|
||||||
|
#include <libcpu/omap3.h>
|
||||||
|
|
||||||
|
#define setbit(a,x) (a | (1<<x))
|
||||||
|
#define bcd(a) ((a & 0x0f)+ (((a & 0xf0) >> 4 )*10))
|
||||||
|
#define dec(a) (((a / 10) << 4) | (a % 10))
|
||||||
|
#define WRITE_WAIT_MAX_COUNT 10000
|
||||||
|
|
||||||
|
rtems_device_minor_number RTC_Minor;
|
||||||
|
size_t RTC_Count = 1;
|
||||||
|
|
||||||
|
static void rtc_write_enable(void);
|
||||||
|
static void rtc_write_disable(void);
|
||||||
|
static int rtc_write_wait(void);
|
||||||
|
static void rtc_clk_init(void);
|
||||||
|
void rtc_init(int minor);
|
||||||
|
void print_time(void);
|
||||||
|
int am335x_rtc_gettime(int minor,rtems_time_of_day *t);
|
||||||
|
int am335x_rtc_settime(int minor, const rtems_time_of_day *t);
|
||||||
|
void am335x_rtc_debug(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* probe for a rtc. we always claim to have one.
|
||||||
|
*/
|
||||||
|
static bool am335x_rtc_probe (int minor)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write key values to kick0 and kick1 registers to enable write access
|
||||||
|
*/
|
||||||
|
static void rtc_write_enable(void)
|
||||||
|
{
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,AM335X_RTC_KICK0_KEY);
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,AM335X_RTC_KICK1_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write random (0x11111111) value to kick0 and kick1 registers to disable write access
|
||||||
|
*/
|
||||||
|
static void rtc_write_disable(void)
|
||||||
|
{
|
||||||
|
/* Write some random value other than key to disable*/
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,0x11111111);
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,0x11111111);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait till busy bit is reset
|
||||||
|
*/
|
||||||
|
static int rtc_write_wait(void)
|
||||||
|
{
|
||||||
|
int i = WRITE_WAIT_MAX_COUNT;
|
||||||
|
while((mmio_read(AM335X_RTC_BASE+AM335X_RTC_STATUS_REG) & 0x1) && (i--));
|
||||||
|
|
||||||
|
if(i == 0)
|
||||||
|
return RTEMS_RESOURCE_IN_USE;
|
||||||
|
else
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize RTC clock
|
||||||
|
*/
|
||||||
|
static void rtc_clk_init(void)
|
||||||
|
{
|
||||||
|
uint32_t a = 0x0;
|
||||||
|
|
||||||
|
a = setbit(a,1);
|
||||||
|
/* IDLEST = 0x0 & MODULEMODE = 0x1*/
|
||||||
|
mmio_write(CM_RTC_BASE+CM_RTC_RTC_CLKCTRL,a);
|
||||||
|
a = 0x0;
|
||||||
|
|
||||||
|
/*32K rtc clock active*/
|
||||||
|
a = setbit(a,9);
|
||||||
|
a = setbit(a,8);
|
||||||
|
mmio_write(CM_RTC_BASE+CM_RTC_CLKSTCTRL,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtc_init(int minor)
|
||||||
|
{
|
||||||
|
uint32_t a = 0x0;
|
||||||
|
|
||||||
|
rtc_clk_init();
|
||||||
|
/*
|
||||||
|
* Steps to enable RTC
|
||||||
|
* 1. Enable the module clock domains (rtc_clk_init).
|
||||||
|
* 2. Enable the RTC module using CTRL_REG.RTC_disable. (Default enabled. Nothing done)
|
||||||
|
* 3. Enable the 32K clock from PER PLL, if using the internal RTC oscillator.
|
||||||
|
* 4. Write to the kick registers (KICK0R, KICK1R) in the RTC.
|
||||||
|
* 5. Configure the timer in RTCSS for desired application (set time and date, alarm wakeup, and so on).
|
||||||
|
* 6. Start the RTC (in CTRL_REG.STOP_RTC).
|
||||||
|
*/
|
||||||
|
rtc_write_enable();
|
||||||
|
a = setbit(a,0);
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_SYSCONFIG,a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK);
|
||||||
|
a = setbit(a,6);
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK,a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG);
|
||||||
|
a = setbit(a,0);
|
||||||
|
mmio_write(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG,a);
|
||||||
|
|
||||||
|
rtc_write_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int am335x_rtc_gettime(int minor,rtems_time_of_day *t)
|
||||||
|
{
|
||||||
|
uint32_t a = 0x0;
|
||||||
|
|
||||||
|
if(minor != 0)
|
||||||
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
|
||||||
|
t->second = bcd(a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
|
||||||
|
t->minute = bcd(a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
|
||||||
|
t->hour = bcd(a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
|
||||||
|
t->day = bcd(a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
|
||||||
|
t->month = bcd(a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
|
||||||
|
t->year = bcd(a)+2000;
|
||||||
|
t->ticks=0;
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int am335x_rtc_settime(int minor,const rtems_time_of_day *t)
|
||||||
|
{
|
||||||
|
uint32_t a=0x0;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if(minor != 0)
|
||||||
|
return RTEMS_INVALID_NUMBER;
|
||||||
|
|
||||||
|
rtc_write_enable();
|
||||||
|
|
||||||
|
/* Wait till the busy bit is reset to write again*/
|
||||||
|
a = t->second;
|
||||||
|
rv=rtc_write_wait();
|
||||||
|
if(rv != RTEMS_SUCCESSFUL)
|
||||||
|
return rv;
|
||||||
|
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_SECS,dec(a) & 0x7f);
|
||||||
|
|
||||||
|
a = t->minute;
|
||||||
|
rv=rtc_write_wait();
|
||||||
|
if(rv != RTEMS_SUCCESSFUL)
|
||||||
|
return rv;
|
||||||
|
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MINS,dec(a) & 0x7f);
|
||||||
|
|
||||||
|
a = t->hour;
|
||||||
|
rv=rtc_write_wait();
|
||||||
|
if(rv != RTEMS_SUCCESSFUL)
|
||||||
|
return rv;
|
||||||
|
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_HOURS,dec(a) & 0x3f);
|
||||||
|
|
||||||
|
a = t->day;
|
||||||
|
rv=rtc_write_wait();
|
||||||
|
if(rv != RTEMS_SUCCESSFUL)
|
||||||
|
return rv;
|
||||||
|
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_DAYS,dec(a) & 0x3f);
|
||||||
|
|
||||||
|
a = t->month;
|
||||||
|
rv=rtc_write_wait();
|
||||||
|
if(rv != RTEMS_SUCCESSFUL)
|
||||||
|
return rv;
|
||||||
|
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MONTHS,dec(a) & 0x1f);
|
||||||
|
|
||||||
|
a = t->year;
|
||||||
|
rv=rtc_write_wait();
|
||||||
|
if(rv != RTEMS_SUCCESSFUL)
|
||||||
|
return rv;
|
||||||
|
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_YEARS,(dec(a)%100) & 0xff);
|
||||||
|
|
||||||
|
rtc_write_disable();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BBB_DEBUG
|
||||||
|
void print_time(void)
|
||||||
|
{
|
||||||
|
uint32_t a = 0x0;
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
|
||||||
|
printk("\n\rSecs %x",a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
|
||||||
|
printk("\n\rMins %x",a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
|
||||||
|
printk("\n\rHours %x",a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
|
||||||
|
printk("\n\rDays %x",a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
|
||||||
|
printk("\n\r Months %x",a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
|
||||||
|
printk("\n\rYears %x",a);
|
||||||
|
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_WEEKS);
|
||||||
|
printk("\n\rWeeks %x",a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void am335x_rtc_debug(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
rtems_time_of_day t,r;
|
||||||
|
|
||||||
|
t.second = 1;
|
||||||
|
t.minute = 1;
|
||||||
|
t.hour = 1;
|
||||||
|
t.day = 7;
|
||||||
|
t.month = 3;
|
||||||
|
t. year = 2015;
|
||||||
|
|
||||||
|
am335x_rtc_settime(0,&t);
|
||||||
|
am335x_rtc_gettime(0,&r);
|
||||||
|
|
||||||
|
printk("Secs %x",r.second);
|
||||||
|
printk("Mins %x",r.minute);
|
||||||
|
printk("Hours %x",r.hour);
|
||||||
|
printk("Days %x",r.day);
|
||||||
|
printk("Months %x",r.month);
|
||||||
|
printk("Years %x",r.year);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* driver function table.
|
||||||
|
*/
|
||||||
|
rtc_fns am335x_rtc_fns = {
|
||||||
|
rtc_init,
|
||||||
|
am335x_rtc_gettime,
|
||||||
|
am335x_rtc_settime
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the following table configures the RTC drivers used in this BSP
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtc_tbl RTC_Table[] = {
|
||||||
|
{
|
||||||
|
"/dev/rtc", /* sDeviceName */
|
||||||
|
RTC_CUSTOM, /* deviceType */
|
||||||
|
&am335x_rtc_fns, /* pDeviceFns */
|
||||||
|
am335x_rtc_probe, /* deviceProbe */
|
||||||
|
NULL, /* pDeviceParams */
|
||||||
|
0, /* ulCtrlPort1 */
|
||||||
|
0, /* ulDataPort */
|
||||||
|
NULL, /* getRegister */
|
||||||
|
NULL /* setRegister */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -280,3 +280,23 @@
|
|||||||
/* Command posted status */
|
/* Command posted status */
|
||||||
#define AM335X_WDT_WSPR 0x48
|
#define AM335X_WDT_WSPR 0x48
|
||||||
/* Activate/deactivate sequence */
|
/* Activate/deactivate sequence */
|
||||||
|
|
||||||
|
/* RTC registers */
|
||||||
|
#define AM335X_RTC_BASE 0x44E3E000
|
||||||
|
#define AM335X_RTC_SECS 0x0
|
||||||
|
#define AM335X_RTC_MINS 0x4
|
||||||
|
#define AM335X_RTC_HOURS 0x8
|
||||||
|
#define AM335X_RTC_DAYS 0xc
|
||||||
|
#define AM335X_RTC_MONTHS 0x10
|
||||||
|
#define AM335X_RTC_YEARS 0x14
|
||||||
|
#define AM335X_RTC_WEEKS 0x18
|
||||||
|
#define AM335X_RTC_CTRL_REG 0x40
|
||||||
|
#define AM335X_RTC_STATUS_REG 0x44
|
||||||
|
#define AM335X_RTC_REV_REG 0x74
|
||||||
|
#define AM335X_RTC_SYSCONFIG 0x78
|
||||||
|
#define AM335X_RTC_KICK0 0x6c
|
||||||
|
#define AM335X_RTC_KICK1 0x70
|
||||||
|
#define AM335X_RTC_OSC_CLOCK 0x54
|
||||||
|
|
||||||
|
#define AM335X_RTC_KICK0_KEY 0x83E70B13
|
||||||
|
#define AM335X_RTC_KICK1_KEY 0x95A4F1E0
|
||||||
|
|||||||
@@ -288,6 +288,12 @@
|
|||||||
#define CLKSEL_TIMER7_CLK_SEL_SEL3 (0x2 << 0) /* Select CLK_32KHZ clock */
|
#define CLKSEL_TIMER7_CLK_SEL_SEL3 (0x2 << 0) /* Select CLK_32KHZ clock */
|
||||||
#define CLKSEL_TIMER7_CLK_SEL_SEL4 (0x3 << 0) /* Reserved */
|
#define CLKSEL_TIMER7_CLK_SEL_SEL4 (0x3 << 0) /* Reserved */
|
||||||
|
|
||||||
|
/*RTC CLOCK BASE & Registers*/
|
||||||
|
#define CM_RTC_BASE 0x44E00800
|
||||||
|
#define CM_RTC_RTC_CLKCTRL 0x0
|
||||||
|
#define CM_RTC_CLKSTCTRL 0x4
|
||||||
|
|
||||||
|
|
||||||
#define OMAP3_CLKSEL_GPT1 (1 << 0)
|
#define OMAP3_CLKSEL_GPT1 (1 << 0)
|
||||||
#define OMAP3_CLKSEL_GPT10 (1 << 6)
|
#define OMAP3_CLKSEL_GPT10 (1 << 6)
|
||||||
#define OMAP3_CLKSEL_GPT11 (1 << 7)
|
#define OMAP3_CLKSEL_GPT11 (1 << 7)
|
||||||
|
|||||||
Reference in New Issue
Block a user