source: rtems/bsps/arm/lpc32xx/rtc/rtc-config.c @ ba619b7f

Last change on this file since ba619b7f was ba619b7f, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 21:38:20

bsps/arm/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSBSPsARMLPC32XX
5 *
6 * @brief RTC configuration.
7 */
8
9/*
10 * Copyright (c) 2009-2011 embedded brains GmbH.  All rights reserved.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#include <libchip/rtc.h>
18
19#include <bsp.h>
20#include <bsp/lpc32xx.h>
21#include <rtems/rtems/clockimpl.h>
22
23#include <time.h>
24
25#define LPC32XX_RTC_COUNT 1U
26
27#define LPC32XX_RTC_COUNTER_DELTA 0xfffffffeU
28
29#define LPC32XX_RTC_KEY 0xb5c13f27U
30
31#define LPC32XX_RTC_CTRL_FORCE_ONSW (1U << 7)
32#define LPC32XX_RTC_CTRL_STOP (1U << 6)
33#define LPC32XX_RTC_CTRL_RESET (1U << 4)
34#define LPC32XX_RTC_CTRL_MATCH_1_ONSW (1U << 3)
35#define LPC32XX_RTC_CTRL_MATCH_0_ONSW (1U << 2)
36#define LPC32XX_RTC_CTRL_MATCH_1_INTR (1U << 1)
37#define LPC32XX_RTC_CTRL_MATCH_0_INTR (1U << 0)
38
39static void lpc32xx_rtc_set(uint32_t val)
40{
41  unsigned i = lpc32xx_arm_clk() / LPC32XX_OSCILLATOR_RTC;
42
43  lpc32xx.rtc.ctrl |= LPC32XX_RTC_CTRL_STOP;
44  lpc32xx.rtc.ucount = val;
45  lpc32xx.rtc.dcount = LPC32XX_RTC_COUNTER_DELTA - val;
46  lpc32xx.rtc.ctrl &= ~LPC32XX_RTC_CTRL_STOP;
47
48  /* It needs some time before we can read the values back */
49  while (i != 0) {
50    __asm__ volatile ("nop");
51    --i;
52  }
53}
54
55static void lpc32xx_rtc_reset(void)
56{
57  lpc32xx.rtc.ctrl = LPC32XX_RTC_CTRL_RESET;
58  lpc32xx.rtc.ctrl = 0;
59  lpc32xx.rtc.key = LPC32XX_RTC_KEY;
60  lpc32xx_rtc_set(0);
61}
62
63static void lpc32xx_rtc_initialize(int minor)
64{
65  uint32_t up_first = 0;
66  uint32_t up_second = 0;
67  uint32_t down_first = 0;
68  uint32_t down_second = 0;
69
70  if (lpc32xx.rtc.key != LPC32XX_RTC_KEY) {
71    lpc32xx_rtc_reset();
72  }
73
74  do {
75    up_first = lpc32xx.rtc.ucount;
76    down_first = lpc32xx.rtc.dcount;
77    up_second = lpc32xx.rtc.ucount;
78    down_second = lpc32xx.rtc.dcount;
79  } while (up_first != up_second || down_first != down_second);
80
81  if (up_first + down_first != LPC32XX_RTC_COUNTER_DELTA) {
82    lpc32xx_rtc_reset();
83  }
84}
85
86static int lpc32xx_rtc_get_time(int minor, rtems_time_of_day *tod)
87{
88  struct timeval now = {
89    .tv_sec = lpc32xx.rtc.ucount,
90    .tv_usec = 0
91  };
92  struct tm time;
93
94  gmtime_r(&now.tv_sec, &time);
95
96  tod->year   = time.tm_year + 1900;
97  tod->month  = time.tm_mon + 1;
98  tod->day    = time.tm_mday;
99  tod->hour   = time.tm_hour;
100  tod->minute = time.tm_min;
101  tod->second = time.tm_sec;
102  tod->ticks  = 0;
103
104  return RTEMS_SUCCESSFUL;
105}
106
107static int lpc32xx_rtc_set_time(int minor, const rtems_time_of_day *tod)
108{
109  lpc32xx_rtc_set(_TOD_To_seconds(tod));
110
111  return 0;
112}
113
114static bool lpc32xx_rtc_probe(int minor)
115{
116  return true;
117}
118
119const rtc_fns lpc32xx_rtc_ops = {
120  .deviceInitialize = lpc32xx_rtc_initialize,
121  .deviceGetTime = lpc32xx_rtc_get_time,
122  .deviceSetTime = lpc32xx_rtc_set_time
123};
124
125size_t RTC_Count = LPC32XX_RTC_COUNT;
126
127rtc_tbl RTC_Table [LPC32XX_RTC_COUNT] = {
128  {
129    .sDeviceName = "/dev/rtc",
130    .deviceType = RTC_CUSTOM,
131    .pDeviceFns = &lpc32xx_rtc_ops,
132    .deviceProbe = lpc32xx_rtc_probe,
133    .pDeviceParams = NULL,
134    .ulCtrlPort1 = 0,
135    .ulDataPort = 0,
136    .getRegister = NULL,
137    .setRegister = NULL
138  }
139};
Note: See TracBrowser for help on using the repository browser.