FreeNOS
Time.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 Coen Bijlsma
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <FreeNOS/User.h>
19 #include <Macros.h>
20 #include <Types.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #include "Time.h"
26 
27 Time::Time(const u32 inode)
29 {
30  m_identifier << "time0";
31 }
32 
34 {
35  return FileSystem::Success;
36 }
37 
39  Size & size,
40  const Size offset)
41 {
42  unsigned int year, month, day, hour, min, sec = 0, time;
43  char tmp[16];
44  int n;
45 
46  // PHONY read
47  if(offset >= 10)
48  {
49  size = 0;
50  return FileSystem::Success;
51  }
52 
53  // If UIP is clear, then we have >= 244 microseconds before
54  // RTC registers will be updated. Spec sheet says that this
55  // is the reliable way to read RTC - registers. If UIP is set
56  // then the register access might be invalid
57  while((readCMOS(RTC_STATUS_A) & RTC_UIP));
58 
59  // Read the date/time values from the CMOS
60  sec = readCMOS(RTC_SECONDS);
61  min = readCMOS(RTC_MINUTES);
62  hour = readCMOS(RTC_HOURS);
64  month = readCMOS(RTC_MONTH);
65  year = readCMOS(RTC_YEAR);
66 
67  // Check if the time values are stored in binary or BCD format
68  if( (readCMOS(RTC_STATUS_B) & RTC_BCD) )
69  {
70  // Convert from binary coded decimal (bcd) to machine numbers
71  sec = bcd2bin(sec);
72  min = bcd2bin(min);
73  hour = bcd2bin(hour);
74  day = bcd2bin(day);
75  month = bcd2bin(month);
76  year = bcd2bin(year);
77  }
78 
79  // Assume that a two-digit year is after 2000
80  if(year < 100)
81  {
82  year += CMOS_YEARS_OFFS;
83  }
84 
85  // Format as an ASCII string
86  time = mktime(year, month, day, hour, min, sec);
87  n = snprintf(tmp, size < sizeof(tmp) ? size : sizeof(tmp), "%u", time);
88  buffer.write(tmp, n);
89 
90  // Done
91  return FileSystem::Success;
92 }
93 
94 unsigned char Time::readCMOS(unsigned char addr)
95 {
96  m_io.outb(RTC_PORT(0), addr);
97  return m_io.inb(RTC_PORT(1));
98 }
99 
100 unsigned Time::bcd2bin(unsigned char val)
101 {
102  return (val & 0x0f) + (val >> 4) * 10;
103 }
RTC_STATUS_A
#define RTC_STATUS_A
Offset in CMOS for the status A register.
Definition: Time.h:68
Macros.h
CMOS_YEARS_OFFS
#define CMOS_YEARS_OFFS
Assume that a two-digit year is after 2000.
Definition: Time.h:65
Types.h
Time::initialize
virtual FileSystem::Result initialize()
Initialize the time device.
Definition: Time.cpp:33
string.h
RTC_YEAR
#define RTC_YEAR
Offset in the CMOS for the current year.
Definition: Time.h:62
Time::bcd2bin
unsigned bcd2bin(unsigned char val)
Convert from binary coded decimal to binary form.
Definition: Time.cpp:100
Device
Abstract device class interface.
Definition: Device.h:35
Time::Time
Time(const u32 inode)
Constructor.
Definition: Time.cpp:27
mktime
unsigned long mktime(const unsigned int year, const unsigned int month, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec)
Copyright (C) 2009 Coen Bijlsma.
Definition: time.cpp:20
RTC_HOURS
#define RTC_HOURS
Offset in the CMOS for the current number of hours.
Definition: Time.h:45
RTC_DAY_OF_MONTH
#define RTC_DAY_OF_MONTH
Offset in the CMOS for the current day of the month.
Definition: Time.h:51
FileSystem::Success
@ Success
Definition: FileSystem.h:54
RTC_UIP
#define RTC_UIP
Update in progress flag.
Definition: Time.h:74
RTC_BCD
#define RTC_BCD
Time/date in binary/BCD flag.
Definition: Time.h:83
RTC_STATUS_B
#define RTC_STATUS_B
Offset in CMOS for the status B register.
Definition: Time.h:71
IOBuffer
Abstract Input/Output buffer.
Definition: IOBuffer.h:37
stdio.h
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
Time.h
Device::m_identifier
String m_identifier
Unique identifier for this Device.
Definition: Device.h:79
FileSystem::CharacterDeviceFile
@ CharacterDeviceFile
Definition: FileSystem.h:75
Time::read
virtual FileSystem::Result read(IOBuffer &buffer, Size &size, const Size offset)
Read time.
Definition: Time.cpp:38
FileSystem::Result
Result
Result code for filesystem Actions.
Definition: FileSystem.h:52
RTC_MONTH
#define RTC_MONTH
Offset in the CMOS for the current month.
Definition: Time.h:54
FileSystem
Definition: FileSystem.h:31
IOBuffer::write
FileSystem::Result write(const void *buffer, const Size size, const Size offset=ZERO)
Write bytes to the I/O buffer.
Definition: IOBuffer.cpp:180
stdlib.h
RTC_PORT
#define RTC_PORT(x)
The base I/O port of the CMOS.
Definition: Time.h:36
RTC_MINUTES
#define RTC_MINUTES
Offset in the CMOS for the current number of minutes.
Definition: Time.h:42
Time::readCMOS
unsigned char readCMOS(unsigned char addr)
Returns the value stored at the given address from the CMOS.
Definition: Time.cpp:94
snprintf
int snprintf(char *buffer, unsigned int size, const char *fmt,...)
Write a formatted string into a buffer.
Definition: snprintf.cpp:22
RTC_SECONDS
#define RTC_SECONDS
Offset in the CMOS for the current number of seconds.
Definition: Time.h:39
Time::m_io
Arch::IO m_io
Port I/O object.
Definition: Time.h:154