source: rtems/c/src/lib/libbsp/m68k/efi68k/startup/efi68k_tcp.c @ a858910

4.104.114.84.95
Last change on this file since a858910 was 18647b7, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 25, 1997 at 4:58:10 PM

updated to reflect new license per John Gwynne's permission.

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 *-------------------------------------------------------------------
3 *
4 * This file contains the subroutines necessary to initalize
5 * the DP8750A TCP on the efi68k board.
6 *
7 * This file has been created by John S. Gwynne for the efi68k
8 * project.
9 *
10 *  The license and distribution terms for this file may in
11 *  the file LICENSE in this distribution or at
12 *  http://www.OARcorp.com/rtems/license.html.
13 *
14 *------------------------------------------------------------------
15 *
16 *  $Id$
17 */
18
19#include <bsp.h>
20
21/* define tcp struct pointers */
22struct clock_ram * const tcp_power_up =
23   (struct clock_ram * const)(0x16*2+TCP_BASE_ADDRESS);
24
25struct clock_ram * const tcp_power_down =
26   (struct clock_ram * const)(0x1b*2+TCP_BASE_ADDRESS);
27
28struct clock_counters * const tcp_clock =
29   (struct clock_counters * const)(0x05*2+TCP_BASE_ADDRESS);
30
31struct clock_ram * const tcp_save_ram =
32   (struct clock_ram * const)(0x19*2+TCP_BASE_ADDRESS);
33
34#define X_DELAY 300             /* time-out delay for crystal start */
35#define X1_DELAY 100000
36
37void tcp_delay(int count)
38{
39  int i;
40  /* change latter to use a counter !!! */
41  for (i=0;i<count/4;i++);
42}
43
44void tcp_init()
45{
46  unsigned char low_bat, osc_fail, power_up;
47  unsigned char mon, dom, hrs, min, sec;
48  int i, count;
49
50  /* delay about 60us to ensure TCP is not locked-out */
51  tcp_delay(80);
52
53  /* set normal supply mode and reset test mode bit */
54  *MSR = 0;
55  *PFR = 0;
56
57  /* save oscillator failure condition */
58  *MSR = 0;                     /* set RS and PS to zero */
59  osc_fail = (*PFR & OSF ? 1 : 0);
60  *MSR = PS;
61  *RAM_OSC_FAIL = *RAM_OSC_FAIL || osc_fail;
62
63  *MSR = PS;
64  if (*RAM_OSC_FAIL) {
65    power_up = 1;
66    *MSR = PS;
67    *RAM_POWERUP = power_up;
68    /* clear time counters and power up & down ram */
69    *MSR = 0;
70    tcp_clock->hofs = 0;
71    tcp_clock->sec = 0;
72    tcp_clock->min = 0;
73    tcp_clock->hrs = 0;
74    tcp_clock->dom = 1;
75    tcp_clock->mon = 1;
76    tcp_clock->yr = 0x95;
77    tcp_clock->jd0 = 0x01;
78    tcp_clock->jd1 = 0;
79    tcp_clock->dow = 1;
80    *MSR = PS;
81    tcp_power_up->sec = 0;
82    tcp_power_up->min = 0;
83    tcp_power_up->hrs = 0;
84    tcp_power_up->dom = 0;
85    tcp_power_up->mon = 0;
86    tcp_power_down->sec = 0;
87    tcp_power_down->min = 0;
88    tcp_power_down->hrs = 0;
89    tcp_power_down->dom = 0;
90    tcp_power_down->mon = 0;
91  } else {
92    /* save for power-up test */
93    *MSR = 0;
94    power_up = (*IRR & TMSE ? 0 : 1);
95    *MSR = PS;
96    *RAM_POWERUP = power_up;
97
98    /* update tcp_power_up and tcp_power_down on power up */
99    if (power_up) {
100      *MSR = 0;
101      do {
102        *PFR;
103        sec = tcp_clock->sec;
104        min = tcp_clock->min;
105        hrs = tcp_clock->hrs;
106        dom = tcp_clock->dom;
107        mon = tcp_clock->mon;
108      } while (*PFR & R_1S);
109      *MSR = PS;
110      tcp_power_up->sec = sec;
111      tcp_power_up->min = min;
112      tcp_power_up->hrs = hrs;
113      tcp_power_up->dom = dom;
114      tcp_power_up->mon = ( (((mon>>4)*10)+(mon&0xf))>12 ? 0 : mon );
115      *MSR = 0;                 /* save ram is not running */
116      sec = tcp_save_ram->sec;
117      min = tcp_save_ram->min;
118      hrs = tcp_save_ram->hrs;
119      dom = tcp_save_ram->dom;
120      mon = tcp_save_ram->mon;
121      *MSR = PS;
122      tcp_power_down->sec = sec;
123      tcp_power_down->min = min;
124      tcp_power_down->hrs = hrs;
125      tcp_power_down->dom = dom;
126      tcp_power_down->mon = ( (((mon>>4)*10)+(mon&0xf))>12 ? 0 : mon );
127    }
128  }
129
130  /* load interrupt routing reg. PF must be enabled to test
131     for low battery, but I route it to MFO to avoid any
132     potential problems */
133  *MSR = 0;
134  *IRR = PF_R | TMSE;
135
136  /* initialize the output mode register */
137  *MSR = RS;
138  *OMR = IP | MP | MO;          /* INTR active low and push/pull */
139
140  /* initialize interrupt control reg 0 */
141  *MSR = RS;
142  *ICR0 = 0;                    /* disable all interrupts */
143
144  /* initialize interrupt control reg 1 */
145  *MSR = RS;
146  *ICR1 = PFE;                  /* this also enables the low battery
147                                   detection circuit. */
148
149  /* I had trouble getting the tcp to be completely
150     flexible to supply modes (i.e., automatically
151     selecting single or normal battery backup modes based
152     on inputs at power-up. If single supply mode is
153     selected, the low battery detect is disabled and the
154     low battery detect in normal mode does not seem to
155     detect when no battery is present at all. If normal
156     mode is selected and no battery is present, the
157     crystal will stop, but only if reset after
158     power-up. It would seem that after a power-up reset,
159     with no battery, the chip may automaticlly switch to
160     single supply mode which disables the low battery
161     detection circuit.)  The following software tests
162     works for all permiatations of low batt, reset,
163     power-on reset, battery, no battery, battery on after
164     Vcc,....  *except* for battery switched on for the
165     first time before power up in which case the chip
166     will still be in single suppy mode till restarted (a
167     second call to tcp_init such as when the time is set
168     or a reboot.)  The timer/clock itself should always
169     be completely functional regardless of the supply
170     mode. */
171
172
173  /* initialize the real time mode register */
174  /* note: write mode bits *before* CSS, then set CSS */
175  *MSR = 0;                     /* clear roll-over */
176  *PFR;
177  count=1;
178  for (i=0;i<X_DELAY;i++) {     /* loop till xtal starts */
179    *MSR = RS;
180    *RTMR = (*RTMR & (LY0 | LY1 )) | CSS;
181    *MSR = 0;
182    if (*PFR & R_1MS) 
183      if (!(count--)) break;
184  }
185  if (i>=X_DELAY) {
186    {
187      /* xtal didn't start; try single supply mode */
188      *MSR = 0;                 /* single supply */
189      *PFR = OSF;
190      *MSR = 0;                 /* clear roll-over */
191      *PFR;
192      count=1;
193      for (i=0;i<X1_DELAY;i++) {        /* loop till xtal starts */
194        *MSR = RS;
195        *RTMR = (*RTMR & (LY0 | LY1 )) | CSS;
196        *MSR = 0;
197        if (*PFR & R_1MS)
198          if (!(count--)) break;
199      }
200      if (i>=X1_DELAY) {
201        /* xtal didn't start; fail tcp */
202        *MSR = PS;
203        *RAM_TCP_FAILURE = 1;
204        *MSR = PS;
205        *RAM_SINGLE_SUP=1;
206      } else {
207        *MSR = PS;
208        *RAM_TCP_FAILURE = 0;
209        *MSR = PS;
210        *RAM_SINGLE_SUP=1;
211      }
212    }
213  } else {
214    *MSR = PS;
215    *RAM_TCP_FAILURE = 0;
216    *MSR = PS;
217    *RAM_SINGLE_SUP=0;
218  }
219
220  /* wait for low battery detection circuit to stabalize */
221  tcp_delay(1000);
222
223  /* battery test */
224  *MSR = 0;
225  low_bat = (*IRR & LBF ? 1 : 0 );
226  *MSR = PS;
227  *RAM_LOWBAT = low_bat & !(*RAM_SINGLE_SUP);
228
229  /* reset pending interrupts */
230  *MSR = ( PER | AL | T0 | T1 );
231
232  /* resync the time save ram with the clock */
233  tcp_save_ram->sec = 0;
234  tcp_save_ram->min = 0;
235  tcp_save_ram->hrs = 0;
236  tcp_save_ram->dom = 0;
237  tcp_save_ram->mon = 0;
238} 
Note: See TracBrowser for help on using the repository browser.