Skip to content

Commit f43d55e

Browse files
Merge pull request #63 from Code1110/Ds1307div
Added support for the DS1307 RTC and some fixes
2 parents bbb463b + 70a25c4 commit f43d55e

File tree

10 files changed

+497
-6
lines changed

10 files changed

+497
-6
lines changed
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Raspberry.IO.InterIntegratedCircuit;
4+
using System.Collections;
5+
6+
namespace Raspberry.IO.Components.Clocks.Ds1307
7+
{
8+
/// <summary>
9+
/// Provides functionality for the DS1307 Real-Time Clock.
10+
/// </summary>
11+
/// <remarks>
12+
/// The Clock Module needs to be modified to work with the Raspberry Pi
13+
/// according to this article: http://electronics.stackexchange.com/questions/98361/how-to-modify-ds1307-rtc-to-use-3-3v-for-raspberry-pi
14+
/// The Datasheet can be found here: http://www.alldatasheet.com/datasheet-pdf/pdf/58481/DALLAS/DS1307.html (the Memory Map
15+
/// is on Page 5. Note that the values in RAM are stored in Nibbles).
16+
/// </remarks>
17+
public class Ds1307Connection
18+
{
19+
public I2cDeviceConnection Connection { get; set; }
20+
21+
/// <summary>
22+
/// Creates a new instance of the class using the provided I2C Connection.
23+
/// </summary>
24+
/// <param name="connection">I2C Connection to the Clock.</param>
25+
public Ds1307Connection(I2cDeviceConnection connection)
26+
{
27+
Connection = connection;
28+
}
29+
30+
/// <summary>
31+
/// Reads the Seconds-byte (first byte in the RAM) from the Clock and returns it.
32+
/// </summary>
33+
/// <returns>The Seconds-Byte including the CH-Flag in bit 7.</returns>
34+
private byte ReadSeconds()
35+
{
36+
Connection.Write(0x00);
37+
return Connection.ReadByte();
38+
}
39+
40+
/// <summary>
41+
/// Reads 7 bytes from the Clock and returns them.
42+
/// </summary>
43+
/// <returns>7 Bytes from the Clock.</returns>
44+
private byte[] ReadAll()
45+
{
46+
Connection.Write(0x00);
47+
return Connection.Read(7);
48+
}
49+
50+
/// <summary>
51+
/// Reads the Date and Time from the Ds1307 and returns it.
52+
/// </summary>
53+
/// <returns>Date.</returns>
54+
public DateTime GetDate()
55+
{
56+
return GetDate(ReadAll());
57+
}
58+
59+
/// <summary>
60+
/// Converts the provided bytes to a DateTime.
61+
/// </summary>
62+
/// <param name="input">Bytes that should be converted.</param>
63+
/// <returns>DateTime resulting from the bytes.</returns>
64+
private DateTime GetDate(byte[] input)
65+
{
66+
/* Byte 1: CH-Flag + Seconds (00-59)
67+
* Byte 2: Minutes (00-59)
68+
* Byte 3: 12/24-Flag, AM/PM, Hours (01-12 or 00-23)
69+
* Byte 4: Day of week (1-7)
70+
* Byte 5: Day (01-31)
71+
* Byte 6: Month (01-12)
72+
* Byte 7: Year (00-99)
73+
* Byte 8: Control Register (for enabling/disabling Sqare Wave)
74+
*/
75+
76+
int seconds = input[0];
77+
if (!IsRtcEnabled(input[0])) seconds = seconds - 128; // Remove "CH"-bit from the seconds if present
78+
79+
seconds = NibbleToInt((byte)seconds);
80+
81+
int minutes = NibbleToInt(input[1]);
82+
int hours = NibbleToInt(input[2]);
83+
84+
if ((hours & 64) == 64)
85+
{
86+
throw new NotImplementedException("AM/PM Time is currently not supported.");
87+
// 12 h Format
88+
//if ((hours & 32) == 32)
89+
//{
90+
// //PM
91+
//}
92+
//else
93+
//{
94+
// //AM
95+
//}
96+
}
97+
98+
int dayOfWeek = NibbleToInt(input[3]);
99+
100+
int day = NibbleToInt(input[4]);
101+
int month = NibbleToInt(input[5]);
102+
int year = NibbleToInt(input[6]);
103+
104+
if (year == 0) return new DateTime();
105+
106+
return new DateTime(year + 2000, month, day, hours, minutes, seconds);
107+
}
108+
109+
/// <summary>
110+
/// Writes the provided Date and Time to the Ds1307.
111+
/// </summary>
112+
/// <param name="date">The Date that should be set.</param>
113+
public void SetDate(DateTime date)
114+
{
115+
List<byte> toWrite = new List<byte>();
116+
117+
toWrite.Add(0x00);
118+
toWrite.Add(SetEnabledDisableRtc(IntToNibble(date.Second), !IsRtcEnabled()));
119+
toWrite.Add(IntToNibble(date.Minute));
120+
toWrite.Add(IntToNibble(date.Hour));
121+
toWrite.Add(Convert.ToByte(date.DayOfWeek));
122+
toWrite.Add(IntToNibble(date.Day));
123+
toWrite.Add(IntToNibble(date.Month));
124+
toWrite.Add(IntToNibble(Convert.ToInt16(date.ToString("yy"), 10)));
125+
126+
Connection.Write(toWrite.ToArray());
127+
}
128+
129+
/// <summary>
130+
/// Enables the Clock.
131+
/// </summary>
132+
public void EnableRtc()
133+
{
134+
// CH=1: Disabled, CH=0: Enabled
135+
byte seconds = ReadSeconds();
136+
if (IsRtcEnabled(seconds)) return;
137+
138+
Connection.Write(0x00, SetEnabledDisableRtc(seconds, false));
139+
}
140+
141+
/// <summary>
142+
/// Disables the Clock. When the Clock is diabled, it not ticking.
143+
/// </summary>
144+
public void DisableRtc()
145+
{
146+
byte seconds = ReadSeconds();
147+
if (!IsRtcEnabled(seconds)) return;
148+
149+
Connection.Write(0x00, SetEnabledDisableRtc(seconds, true));
150+
}
151+
152+
/// <summary>
153+
/// Disables or enables the Clock.
154+
/// </summary>
155+
/// <param name="seconds">The byte that contains the seconds and the CH-Flag.</param>
156+
/// <param name="disable">true will disable the Clock, false will enable it.</param>
157+
/// <returns></returns>
158+
/// <remarks>The disable/enabled-Flag is stored in bit 7 within the seconds-byte.</remarks>
159+
private byte SetEnabledDisableRtc(byte seconds, bool disable)
160+
{
161+
BitArray bits = new BitArray(new byte[] { seconds });
162+
bits.Set(7, disable);
163+
164+
byte[] result = new byte[1];
165+
bits.CopyTo(result, 0);
166+
167+
return result[0];
168+
}
169+
170+
/// <summary>
171+
/// Returns true, if the Clock is enabled, otherwise false is returned.
172+
/// </summary>
173+
/// <returns>true: Clock is enabled, false: Clock is diabled.</returns>
174+
public bool IsRtcEnabled()
175+
{
176+
return IsRtcEnabled(ReadSeconds());
177+
}
178+
179+
/// <summary>
180+
/// Returns true, if the Clock is enabled, otherwise false.
181+
/// </summary>
182+
/// <param name="seconds">The byte, that contains the seconds and the CH-Flag.</param>
183+
/// <returns>true: Clock is enabled, false: Clock is diabled.</returns>
184+
private bool IsRtcEnabled(byte seconds)
185+
{
186+
return !((seconds & 128) == 128);
187+
}
188+
189+
/// <summary>
190+
/// Resets the Clock to the Factory Defaults.
191+
/// </summary>
192+
public void ResetToFactoryDefaults()
193+
{
194+
// The Factory Default is: 80,00,00,01,01,01,00,B3
195+
Connection.Write(0x00, 0x80, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00);
196+
}
197+
198+
/// <summary>
199+
/// Writes the current System Date to the Clock.
200+
/// </summary>
201+
public void SystemTimeToRtc()
202+
{
203+
SetDate(DateTime.Now);
204+
}
205+
206+
/// <summary>
207+
/// Converts the specified two-nibble-byte to an integer.
208+
/// </summary>
209+
/// <param name="nibble">Nibble that should be converted.</param>
210+
/// <returns>Integer representation of the nibble.</returns>
211+
private static int NibbleToInt(byte nibble)
212+
{
213+
int result = 0;
214+
result *= 100;
215+
result += (10 * (nibble >> 4));
216+
result += nibble & 0xf;
217+
return result;
218+
}
219+
220+
/// <summary>
221+
/// Converts the specified integer to a two-nibble-byte.
222+
/// </summary>
223+
/// <param name="number">The integer that should be converted. Maximum is 99.</param>
224+
/// <returns>A byte with two nibbles that contains the integer.</returns>
225+
private static byte IntToNibble(int number)
226+
{
227+
int bcd = 0;
228+
for (int digit = 0; digit < 4; ++digit)
229+
{
230+
int nibble = number % 10;
231+
bcd |= nibble << (digit * 4);
232+
number /= 10;
233+
}
234+
return (byte)(bcd & 0xff);
235+
}
236+
}
237+
}

Raspberry.IO.Components/Displays/Hd44780/Hd44780LcdConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ public void Write(string format, TimeSpan animationDelay, params object[] values
403403
if (string.IsNullOrEmpty(line))
404404
continue;
405405

406-
Console.WriteLine(line);
406+
//Console.WriteLine(line);
407407
var bytes = encoding.GetBytes(line);
408408
foreach (var b in bytes)
409409
{

Raspberry.IO.Components/Displays/Ssd1306/Fonts/Fixed1L.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ public class Fixed1L : IFont
100100
new byte[] { (byte)'|', 8, 8, 0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00 },
101101
new byte[] { (byte)'}', 8, 8, 0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00 },
102102
new byte[] { (byte)'~', 8, 8, 0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00 },
103-
new byte[] { (byte)0x7F, 8, 8, 0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00 }
103+
new byte[] { (byte)'ä', 8, 8, 0x00,0x20,0x55,0x54,0x55,0x78,0x00,0x00 },
104+
new byte[] { (byte)'ö', 8, 8, 0x00, 0x39, 0x44, 0x44, 0x39, 0x00, 0x00, 0x00 },
105+
new byte[] { (byte)'ü', 8, 8, 0x00, 0x3D, 0x40, 0x40, 0x7D, 0x00, 0x00, 0x00 },
106+
new byte[] { (byte)0x7F, 8, 8, 0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00 }
104107
};
105108

106109
public byte[][] GetData()

Raspberry.IO.Components/Displays/Ssd1306/Ssd1306Connection.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public void DrawText(IFont font, string text)
136136
SendCommand(
137137
(byte)(0xB0 + cursorY + y), //set page address
138138
(byte)(0x00 + (cursorX & 0x0F)), //set column lower address
139-
(byte)(0x10 + ((cursorX>>4)&0x0F)) //set column higher address
139+
(byte)(0x10 + ((cursorX>>4) & 0x0F)) //set column higher address
140140
);
141141

142142
var data = new byte[fontWidth + 1];
@@ -198,6 +198,16 @@ public void SetScrollProperties(ScrollDirection direction, ScrollSpeed scrollSpe
198198
});
199199
}
200200

201+
/// <summary>
202+
/// Sets the contrast (brightness) of the display. Default is 127.
203+
/// </summary>
204+
/// <param name="contrast">A number between 0 and 255. Contrast increases as the value increases.</param>
205+
public void SetContrast(int contrast)
206+
{
207+
if (contrast < 0 || contrast > 255) throw new ArgumentOutOfRangeException("contrast", "Contrast must be between 0 and 255.");
208+
SendCommand(Command.SetContrast, (byte)contrast);
209+
}
210+
201211
#endregion
202212

203213
#region Private Helpers
@@ -224,7 +234,7 @@ private void Initialize()
224234
Command.SegRemap | 0x1,
225235
Command.ComScanDecrement,
226236
Command.SetComPins, 0x12,
227-
Command.SetContrast, 0x9F,
237+
Command.SetContrast, 0x7F,
228238
Command.SetPreCharge, 0x22,
229239
Command.SetVComDetect, 0x40,
230240
Command.DisplayAllOnResume,

Raspberry.IO.Components/Raspberry.IO.Components.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<Compile Include="..\SharedAssemblyInfo.cs">
5353
<Link>Properties\SharedAssemblyInfo.cs</Link>
5454
</Compile>
55+
<Compile Include="Clocks\Ds1307Connection.cs" />
5556
<Compile Include="Controllers\Tlc59711\ExtensionMethods\ByteExtensionMethods.cs" />
5657
<Compile Include="Controllers\Tlc59711\IPwmChannels.cs" />
5758
<Compile Include="Controllers\Tlc59711\IPwmDevice.cs" />

RaspberrySharp.IO.sln

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 2013
4-
VisualStudioVersion = 12.0.40629.0
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25123.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.GeneralPurpose", "Raspberry.IO.GeneralPurpose\Raspberry.IO.GeneralPurpose.csproj", "{281C71ED-C36D-408E-8BAA-75C381DC17E7}"
77
EndProject
@@ -71,6 +71,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO", "Raspberry.I
7171
EndProject
7272
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raspberry.IO.Interop", "Raspberry.IO.Interop\Raspberry.IO.Interop.csproj", "{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}"
7373
EndProject
74+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Gpio.Ds1307", "Tests\Test.Gpio.Ds1307\Test.Gpio.Ds1307.csproj", "{E9412139-F9EA-4E39-AB7C-CE775ED06C82}"
75+
EndProject
7476
Global
7577
GlobalSection(SolutionConfigurationPlatforms) = preSolution
7678
Debug|Any CPU = Debug|Any CPU
@@ -173,6 +175,10 @@ Global
173175
{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
174176
{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
175177
{689CB6C4-3D23-45DA-8E00-87C28AEA32D0}.Release|Any CPU.Build.0 = Release|Any CPU
178+
{E9412139-F9EA-4E39-AB7C-CE775ED06C82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
179+
{E9412139-F9EA-4E39-AB7C-CE775ED06C82}.Debug|Any CPU.Build.0 = Debug|Any CPU
180+
{E9412139-F9EA-4E39-AB7C-CE775ED06C82}.Release|Any CPU.ActiveCfg = Release|Any CPU
181+
{E9412139-F9EA-4E39-AB7C-CE775ED06C82}.Release|Any CPU.Build.0 = Release|Any CPU
176182
EndGlobalSection
177183
GlobalSection(SolutionProperties) = preSolution
178184
HideSolutionNode = FALSE
@@ -198,6 +204,7 @@ Global
198204
{0BB6C3CE-422E-49F2-9165-DEC06AFE1B1A} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}
199205
{99EB3D1A-F0B7-454E-BB50-9B2F5349BC5B} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}
200206
{CAF876A0-0FCB-44F7-96F1-53704CB6015F} = {C39D0CC3-C0F2-4B58-8779-2CCB5B52534C}
207+
{E9412139-F9EA-4E39-AB7C-CE775ED06C82} = {15ECD485-B3FD-4B6F-8491-7489DFFC89BC}
201208
EndGlobalSection
202209
GlobalSection(MonoDevelopProperties) = preSolution
203210
Policies = $0

Tests/Test.Gpio.Ds1307/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
5+
</startup>
6+
</configuration>

0 commit comments

Comments
 (0)