OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [ppcn_60x/] [tod/] [tod.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  COPYRIGHT (c) 1998 by Radstone Technology
3
 *
4
 *
5
 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
6
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
7
 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
8
 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
9
 *
10
 * You are hereby granted permission to use, copy, modify, and distribute
11
 * this file, provided that this notice, plus the above copyright notice
12
 * and disclaimer, appears in all copies. Radstone Technology will provide
13
 * no support for this code.
14
 *
15
 */
16
 
17
#define MIN_YEAR 1996
18
 
19
#include <stdlib.h>
20
#include "bsp.h"
21
#include "cmos.h"
22
#include "../nvram/mk48t18.h"
23
 
24
#define Bin2BCD(Value) (((Value / 10) << 4) | (Value % 10))
25
#define BCD2Bin(BcdValue) ((BcdValue >> 4) * 10 + (BcdValue & 0x0f))
26
 
27
/*
28
 * Private types
29
 */
30
typedef
31
void
32
(*PTIMESET)
33
(
34
        rtems_time_of_day *pTOD
35
);
36
 
37
typedef
38
boolean
39
(*PTIMEGET)
40
(
41
        rtems_time_of_day *pTOD
42
);
43
 
44
typedef struct _TIME_ENTRY_TABLE
45
{
46
    PTIMESET    SetTime;
47
    PTIMEGET    GetTime;
48
} TIME_ENTRY_TABLE, *PTIME_ENTRY_TABLE;
49
 
50
/*
51
 * Private routines
52
 */
53
 
54
/*
55
 * DS1385 specific routines
56
 */
57
static void timeDsSet(rtems_time_of_day *pTOD);
58
static boolean timeDsGet(rtems_time_of_day *pTOD);
59
 
60
/*
61
 * MK48T18 specific routines
62
 */
63
static void timeMkSet(rtems_time_of_day *pTOD);
64
static boolean timeMkGet(rtems_time_of_day *pTOD);
65
 
66
TIME_ENTRY_TABLE timeDsTable =
67
{
68
        timeDsSet,
69
        timeDsGet
70
};
71
 
72
TIME_ENTRY_TABLE timeMkTable =
73
{
74
        timeMkSet,
75
        timeMkGet
76
};
77
 
78
/*
79
 * Private variables
80
 */
81
static PTIME_ENTRY_TABLE pTimeFunc;
82
 
83
/*
84
 * Mutual-exclusion semaphore
85
 */
86
static rtems_id semRTC;
87
 
88
/*
89
 * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
90
 */
91
rtems_unsigned8
92
GregorianDay(rtems_time_of_day *pTOD)
93
{
94
        boolean isLeap;
95
        unsigned long leapsToDate;
96
        unsigned long lastYear;
97
        unsigned long day;
98
        unsigned long MonthOffset[] = { 0, 31, 59, 90, 120, 151,
99
                                        181, 212, 243, 273, 304, 334 };
100
 
101
        lastYear=pTOD->year-1;
102
 
103
        /*
104
         * Number of leap corrections to apply up to end of last year
105
         */
106
        leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
107
 
108
        /*
109
         * This year is a leap year if it is divisible by 4 except when it is
110
         * divisible by 100 unless it is divisible by 400
111
         *
112
         * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
113
         */
114
        isLeap = (pTOD->year%4==0) &&
115
                         ((pTOD->year%100!=0) || (pTOD->year%400==0));
116
 
117
        if(isLeap && (pTOD->month>2))
118
        {
119
                day=1;
120
        }
121
        else
122
        {
123
                day=0;
124
        }
125
 
126
        day += lastYear*365 + leapsToDate + MonthOffset[pTOD->month-1] +
127
                   pTOD->day;
128
 
129
        return((rtems_unsigned8)(day%7));
130
}
131
 
132
void
133
DsWriteRawClockRegister (
134
        rtems_unsigned8 Register,
135
        rtems_unsigned8 Value
136
)
137
 
138
/*++
139
 
140
Routine Description:
141
 
142
    This routine reads the specified realtime clock register.
143
 
144
    This function was added to bridge the BCD format of the IBM roms
145
    and the binary formate of NT
146
 
147
 
148
Arguments:
149
 
150
    Register - Supplies the number of the register whose value is read.
151
 
152
Return Value:
153
 
154
    The value of the register is returned as the function value.
155
 
156
--*/
157
 
158
{
159
        outport_byte((rtems_unsigned8 *)RTC_PORT, Register & 0x7f);
160
 
161
        /* Read the realtime clock register value. */
162
 
163
        outport_byte((rtems_unsigned8 *)(RTC_PORT + 1), Value);
164
        return;
165
}
166
 
167
rtems_unsigned8
168
DsReadRawClockRegister (
169
        rtems_unsigned8 Register
170
)
171
 
172
/*++
173
 
174
Routine Description:
175
 
176
    This routine reads the specified realtime clock register.
177
 
178
    This function was added to bridge the BCD format of the IBM roms
179
    and the binary formate of NT
180
 
181
 
182
Arguments:
183
 
184
    Register - Supplies the number of the register whose value is read.
185
 
186
Return Value:
187
 
188
    The value of the register is returned as the function value.
189
 
190
--*/
191
 
192
{
193
        rtems_unsigned8 ucDataByte;
194
 
195
        outport_byte((rtems_unsigned8 *)RTC_PORT, Register & 0x7f);
196
 
197
        /* Read the realtime clock register value. */
198
 
199
        inport_byte((rtems_unsigned8 *)(RTC_PORT + 1), ucDataByte);
200
        return ucDataByte;
201
}
202
 
203
void
204
DsWriteClockRegister (
205
        rtems_unsigned8 Register,
206
        rtems_unsigned8 Value
207
)
208
 
209
/*++
210
 
211
Routine Description:
212
 
213
    This routine writes the specified value to the specified realtime
214
    clock register.
215
 
216
Arguments:
217
 
218
    Register - Supplies the number of the register whose value is written.
219
 
220
    Value - Supplies the value that is written to the specified register.
221
 
222
Return Value:
223
 
224
    The value of the register is returned as the function value.
225
 
226
--*/
227
 
228
{
229
        rtems_unsigned8 BcdValue;
230
 
231
        BcdValue = Bin2BCD(Value);
232
        DsWriteRawClockRegister(Register, BcdValue);
233
        return;
234
}
235
 
236
rtems_unsigned8
237
DsReadClockRegister (
238
        rtems_unsigned8 Register
239
)
240
 
241
/*++
242
 
243
Routine Description:
244
 
245
    This routine reads the specified realtime clock register.
246
 
247
Arguments:
248
 
249
    Register - Supplies the number of the register whose value is read.
250
 
251
Return Value:
252
 
253
    The value of the register is returned as the function value.
254
 
255
--*/
256
 
257
{
258
        rtems_unsigned8 BcdValue;
259
 
260
        BcdValue =  DsReadRawClockRegister(Register);
261
        return BCD2Bin(BcdValue);
262
}
263
 
264
void
265
timeDsSet (
266
    rtems_time_of_day *pTOD
267
    )
268
 
269
/*++
270
 
271
Routine Description:
272
 
273
    This routine sets the realtime clock.
274
 
275
    N.B. This routine assumes that the caller has provided any required
276
        synchronization to set the realtime clock information.
277
 
278
Arguments:
279
 
280
    pTOD - Supplies a pointer to a time structure that specifies the
281
        realtime clock information.
282
 
283
Return Value:
284
 
285
    If the power to the realtime clock has not failed, then the time
286
    values are written to the realtime clock and a value of TRUE is
287
    returned. Otherwise, a value of FALSE is returned.
288
 
289
--*/
290
 
291
{
292
        rtems_unsigned8 ucDataByte;
293
        PCMOS_MAP pCMOS = (PCMOS_MAP)0;
294
 
295
        /* If the realtime clock battery is still functioning, then write */
296
        /* the realtime clock values, and return a function value of TRUE. */
297
        /* Otherwise, return a function value of FALSE. */
298
 
299
        ucDataByte = DsReadRawClockRegister(RTC_CONTROL_REGISTERD);
300
        if (ucDataByte&DS1385_REGD_VALID)
301
        {
302
                /* Set the realtime clock control to set the time. */
303
 
304
                ucDataByte = DS1385_REGB_HOURS_FMT | DS1385_REGB_SET_TIME;
305
                DsWriteRawClockRegister(RTC_CONTROL_REGISTERB, ucDataByte);
306
 
307
                /* Write the realtime clock values. */
308
 
309
                DsWriteClockRegister(RTC_YEAR,
310
                                     (rtems_unsigned8)(pTOD->year%100));
311
                if(pTOD->year>=100)
312
                {
313
                        DsWriteClockRegister((rtems_unsigned8)
314
                                             ((unsigned long)&pCMOS->Century),
315
                                             pTOD->year/100);
316
                }
317
                DsWriteClockRegister(RTC_MONTH,
318
                                     (rtems_unsigned8)pTOD->month);
319
                DsWriteClockRegister(RTC_DAY_OF_MONTH,
320
                                     (rtems_unsigned8)pTOD->day);
321
                DsWriteClockRegister(RTC_DAY_OF_WEEK,
322
                                     (rtems_unsigned8)
323
                                     (GregorianDay(pTOD) + 1));
324
                DsWriteClockRegister(RTC_HOUR,
325
                                     (rtems_unsigned8)pTOD->hour);
326
                DsWriteClockRegister(RTC_MINUTE,
327
                                     (rtems_unsigned8)pTOD->minute);
328
                DsWriteClockRegister(RTC_SECOND,
329
                                     (rtems_unsigned8)pTOD->second);
330
 
331
                /* Set the realtime clock control to update the time. */
332
 
333
                ucDataByte &= ~DS1385_REGB_SET_TIME;
334
                DsWriteRawClockRegister(RTC_CONTROL_REGISTERB, ucDataByte);
335
                return;
336
 
337
        }
338
        else
339
        {
340
                return;
341
        }
342
}
343
 
344
boolean
345
timeDsGet (
346
    rtems_time_of_day *pTOD
347
    )
348
 
349
/*++
350
 
351
Routine Description:
352
 
353
    This routine queries the realtime clock.
354
 
355
Arguments:
356
 
357
    pTOD - Supplies a pointer to a time structure that receives
358
        the realtime clock information.
359
 
360
Return Value:
361
 
362
    If the power to the realtime clock has not failed, then the time
363
    values are read from the realtime clock and a value of TRUE is
364
    returned. Otherwise, a value of FALSE is returned.
365
 
366
--*/
367
 
368
{
369
        rtems_unsigned8 ucDataByte;
370
        PCMOS_MAP pCMOS = (PCMOS_MAP)0;
371
 
372
        /* If the realtime clock battery is still functioning, then read */
373
        /* the realtime clock values, and return a function value of TRUE. */
374
        /* Otherwise, return a function value of FALSE. */
375
 
376
        ucDataByte = DsReadRawClockRegister(RTC_CONTROL_REGISTERD);
377
        if(ucDataByte&DS1385_REGD_VALID)
378
        {
379
                /* Wait until the realtime clock is not being updated. */
380
 
381
                do
382
                {
383
                        ucDataByte=DsReadRawClockRegister(RTC_CONTROL_REGISTERA);
384
                } while (ucDataByte&DS1385_REGA_UIP);
385
 
386
                /* Read the realtime clock values. */
387
 
388
                pTOD->year=(rtems_unsigned16)
389
                                  (DsReadClockRegister(
390
                                   (rtems_unsigned8)
391
                                   (unsigned long)&pCMOS->Century)
392
                                  *100 + DsReadClockRegister(RTC_YEAR));
393
                pTOD->month=DsReadClockRegister(RTC_MONTH);
394
                pTOD->day=DsReadClockRegister(RTC_DAY_OF_MONTH);
395
                pTOD->hour=DsReadClockRegister(RTC_HOUR);
396
                pTOD->minute=DsReadClockRegister(RTC_MINUTE);
397
                pTOD->second=DsReadClockRegister(RTC_SECOND);
398
                return TRUE;
399
        }
400
        else
401
        {
402
                return FALSE;
403
        }
404
}
405
 
406
void
407
timeMkSet (
408
    rtems_time_of_day *pTOD
409
    )
410
 
411
/*++
412
 
413
Routine Description:
414
 
415
    This routine sets the realtime clock.
416
 
417
    N.B. This routine assumes that the caller has provided any required
418
        synchronization to set the realtime clock information.
419
 
420
Arguments:
421
 
422
    pTOD - Supplies a pointer to a time structure that specifies the
423
        realtime clock information.
424
 
425
Return Value:
426
 
427
    If the power to the realtime clock has not failed, then the time
428
    values are written to the realtime clock and a value of TRUE is
429
    returned. Otherwise, a value of FALSE is returned.
430
 
431
--*/
432
 
433
{
434
        PMK48T18_NVRAM_MAP pNvRAM = MK48T18_BASE;
435
 
436
        /*
437
         * Set the RTC into write mode
438
         */
439
        pNvRAM->CMOS.Control|=MK48T18_CTRL_WRITE;
440
        EIEIO;
441
 
442
        /*
443
         * Write the realtime clock values.
444
         */
445
 
446
        pNvRAM->CMOS.Year = (rtems_unsigned8)Bin2BCD(pTOD->year%100);
447
        if(pTOD->year>=100)
448
        {
449
            pNvRAM->CMOS.Century=(rtems_unsigned8)
450
                                 Bin2BCD(pTOD->year/100);
451
        }
452
        pNvRAM->CMOS.Month  = (rtems_unsigned8)Bin2BCD(pTOD->month);
453
        pNvRAM->CMOS.Date   = (rtems_unsigned8)Bin2BCD(pTOD->day);
454
        pNvRAM->CMOS.Day    = (rtems_unsigned8)(GregorianDay(pTOD) + 1);
455
        pNvRAM->CMOS.Hour   = (rtems_unsigned8)Bin2BCD(pTOD->hour);
456
        pNvRAM->CMOS.Minute = (rtems_unsigned8)Bin2BCD(pTOD->minute);
457
        pNvRAM->CMOS.Second = (rtems_unsigned8)Bin2BCD(pTOD->second);
458
 
459
        /*
460
         * Set the realtime clock control to update the time.
461
         */
462
 
463
        EIEIO;
464
        pNvRAM->CMOS.Control&=~MK48T18_CTRL_WRITE;
465
}
466
 
467
boolean
468
timeMkGet (
469
    rtems_time_of_day *pTOD
470
    )
471
 
472
/*++
473
 
474
Routine Description:
475
 
476
    This routine queries the realtime clock.
477
 
478
    N.B. This routine is required to provide any synchronization necessary
479
         to query the realtime clock information.
480
 
481
Arguments:
482
 
483
    pTOD - Supplies a pointer to a time structure that receives
484
        the realtime clock information.
485
 
486
Return Value:
487
 
488
    If the power to the realtime clock has not failed, then the time
489
    values are read from the realtime clock and a value of TRUE is
490
    returned. Otherwise, a value of FALSE is returned.
491
 
492
--*/
493
 
494
{
495
        PMK48T18_NVRAM_MAP pNvRAM = MK48T18_BASE;
496
 
497
        /*
498
         * Set the RTC into read mode
499
         */
500
        pNvRAM->CMOS.Control|=MK48T18_CTRL_READ;
501
        EIEIO;
502
 
503
        /*
504
         * Read the realtime clock values.
505
         */
506
 
507
        pTOD->year = (rtems_unsigned16)(100*BCD2Bin(pNvRAM->CMOS.Century)+
508
                                              BCD2Bin(pNvRAM->CMOS.Year));
509
        pTOD->month = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Month);
510
        pTOD->day = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Date);
511
        pTOD->hour = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Hour);
512
        pTOD->minute = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Minute);
513
        pTOD->second = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Second);
514
 
515
        /*
516
         * Set the realtime clock control to normal mode.
517
         */
518
        EIEIO;
519
        pNvRAM->CMOS.Control&=~MK48T18_CTRL_READ;
520
 
521
        return TRUE;
522
}
523
 
524
/*
525
 * Set up entry table
526
 */
527
void
528
InitializeRTC(void)
529
{
530
        rtems_status_code sc;
531
 
532
        switch(ucSystemType)
533
        {
534
                case SYS_TYPE_PPC1:
535
                {
536
                        if(ucBoardRevMaj<5)
537
                        {
538
                                pTimeFunc=&timeDsTable;
539
                                break;
540
                        }
541
                        /*
542
                         * For the 005 and later drop through to the PPC1a support
543
                         */
544
                }
545
 
546
                case SYS_TYPE_PPC1a:
547
                {
548
                        pTimeFunc=&timeMkTable;
549
                        break;
550
                }
551
 
552
                default:
553
                {
554
                        pTimeFunc=&timeDsTable;
555
                        break;
556
                }
557
        }
558
 
559
        /*
560
         * Set up mutex semaphore
561
         */
562
        sc = rtems_semaphore_create (
563
                rtems_build_name ('R', 'T', 'C', 's'),
564
                1,
565
                RTEMS_BINARY_SEMAPHORE |
566
                RTEMS_INHERIT_PRIORITY |
567
                RTEMS_PRIORITY,
568
                RTEMS_NO_PRIORITY,
569
                &semRTC);
570
        if (sc != RTEMS_SUCCESSFUL)
571
        {
572
                rtems_fatal_error_occurred (sc);
573
        }
574
}
575
 
576
void setRealTimeToRTEMS()
577
{
578
        rtems_time_of_day rtc_tod;
579
 
580
        rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
581
        (pTimeFunc->GetTime)(&rtc_tod);
582
        rtems_semaphore_release(semRTC);
583
 
584
        /*
585
         * Millenium fix...
586
         *
587
         * If year is earlier than MIN_YEAR then assume the clock has wrapped from
588
         * 1999 to 1900 so advance by a century
589
         */
590
        if(rtc_tod.year<MIN_YEAR)
591
        {
592
                rtc_tod.year+=100;
593
                rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
594
                (pTimeFunc->SetTime)(&rtc_tod);
595
                rtems_semaphore_release(semRTC);
596
        }
597
 
598
        rtc_tod.ticks=0;
599
 
600
        rtems_clock_set( &rtc_tod );
601
}
602
 
603
void setRealTimeFromRTEMS()
604
{
605
        rtems_time_of_day rtems_tod;
606
 
607
        rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );
608
        rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
609
        (pTimeFunc->SetTime)(&rtems_tod);
610
        rtems_semaphore_release(semRTC);
611
}
612
 
613
 
614
int checkRealTime()
615
{
616
  return 0;
617
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.