mirror of
				https://github.com/dustinbrun/Binaeruhr-Arduino.git
				synced 2025-11-04 00:47:31 +01:00 
			
		
		
		
	Upload 1
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								Binaeruhr.fzz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Binaeruhr.fzz
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Binaeruhr_Platine.fzz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Binaeruhr_Platine.fzz
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Frontplatte.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Frontplatte.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Frontplatte.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Frontplatte.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 203 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								Frontplatte_10x15_Bilderrahmen.fpd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Frontplatte_10x15_Bilderrahmen.fpd
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										46
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					# Arduino Binäruhr 
 | 
				
			||||||
 | 
					Eine Binäruhr basierend auf einem Arduino Nano. Die LEDs werden mit Hilfe von 74HC595 Schieberegistern angesteuert.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[<img src="pictures/Uhr_1.jpg" height="400px">](pictures/Uhr_1.jpg)
 | 
				
			||||||
 | 
					[<img src="pictures/Uhr_2.jpg" height="400px">](pictures/Uhr_2.jpg)
 | 
				
			||||||
 | 
					[<img src="pictures/Uhr_innen.jpg" height="400px">](pictures/Uhr_innen.jpg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Features
 | 
				
			||||||
 | 
					- Einbau in einem IKEA Ribba Bilderrahmen 13x18 cm (bzw. 10x15 cm)
 | 
				
			||||||
 | 
					- Die Zeit wird von einer DS3231 RTC bereitgestellt
 | 
				
			||||||
 | 
					- Ein Taster zum ändern der Anzeige:
 | 
				
			||||||
 | 
					  - Normalmodus: Zeitanzeige - Stunden, Minuten, Sekunden
 | 
				
			||||||
 | 
					  - Datumsanzeige - Tag, Monat, Tag der Woche (1-7)
 | 
				
			||||||
 | 
					  - Temperaturanzeige - Temperaturmessung erfolgt durch das RTC-Modul 
 | 
				
			||||||
 | 
					    - Wenn die Anzeige im Datum- oder Temperaturmodus ist, wechselt sie nach 10 Sekunden automatisch zum Normalmodus zurück
 | 
				
			||||||
 | 
					- Eine extra LED blinkt 2 mal jede Sekunde
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Hardware
 | 
				
			||||||
 | 
					## Schaltplan
 | 
				
			||||||
 | 
					**Im Schaltplan sind keine Vorwiderstände für die einzelnen LEDs eingetragen, diese sollten jedoch verbaut werden! (Wert: 220R)** <br><br>
 | 
				
			||||||
 | 
					[<img src="pictures/Binaeruhr_Schaltplan.png" height="700px">](pictures/Binaeruhr_Schaltplan.png)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Leiterplatte
 | 
				
			||||||
 | 
					[<img src="pictures/Binaeruhr_Platine_Leiterplatte.png" height="400px">](pictures/Binaeruhr_Platine_Leiterplatte.png)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Frontplatte
 | 
				
			||||||
 | 
					Ich habe für den Bilderrahmen eine Frontplatte erstellt (Software: Frontplatten Designer, Schaeffer AG). Diese ist passend für den IKEA Bilderrahmen und kann im Format **10x15 cm** ausgeruckt werden. 
 | 
				
			||||||
 | 
					<br><br>
 | 
				
			||||||
 | 
					[<img src="Frontplatte.png" height="600px">](Frontplatte.png)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Software
 | 
				
			||||||
 | 
					Der Code kann ohne weitere Änderungen verwendet werden. Um die Zeit des RTC-Moduls einzustellen müssen im Code die entsprechenden Zeilen auskommentiert und mit der aktuellen Uhrzeit gefüllt werden. Anschließend muss dieser Code **einmalig** auf dem Arduino ausgeführt werden.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Die Verwendete Bibiliothek für die DS3231 ist im Ordner des Programmes bereits hinterlegt und muss nicht extra heruntergeladen werden. Zusätzlich ist die Quelle der Bibiliothek jedoch im Code verlinkt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Quellen
 | 
				
			||||||
 | 
					- https://pascalstechtips.weebly.com/projekte/arduino-binruhr-v10 
 | 
				
			||||||
 | 
					- DS3231: http://www.rinkydinkelectronics.com/library.php?id=73
 | 
				
			||||||
 | 
					- Software für Frontplatte: https://www.schaeffer-ag.de/frontplatten-designer#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<br><br>
 | 
				
			||||||
 | 
					<p xmlns:dct="http://purl.org/dc/terms/" xmlns:cc="http://creativecommons.org/ns#" class="license-text">This work by <span property="cc:attributionName">Dustin Brunner</span> is licensed under <a rel="license" href="https://creativecommons.org/licenses/by/4.0">CC BY 4.0<img style="height:15px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" /><img style="height:15px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" /></a></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons Lizenzvertrag" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />Dieses Werk von <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Dustin Brunner</span> ist lizenziert unter einer <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Namensnennung 4.0 International Lizenz</a>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								pictures/Binaeruhr_Platine_Leiterplatte.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pictures/Binaeruhr_Platine_Leiterplatte.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 103 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								pictures/Binaeruhr_Schaltplan.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pictures/Binaeruhr_Schaltplan.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 176 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								pictures/Uhr_1.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pictures/Uhr_1.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 234 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								pictures/Uhr_2.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pictures/Uhr_2.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 269 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								pictures/Uhr_innen.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pictures/Uhr_innen.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 375 KiB  | 
							
								
								
									
										179
									
								
								software_binaeruhr/software_binaeruhr.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								software_binaeruhr/software_binaeruhr.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
				
			|||||||
 | 
					#include "src/DS3231.h" //http://www.rinkydinkelectronics.com/library.php?id=73
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DS3231  rtc(SDA, SCL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Pins
 | 
				
			||||||
 | 
					//Pins für Sekunden-Schieberegister
 | 
				
			||||||
 | 
					const int clockPinS   = 4;
 | 
				
			||||||
 | 
					const int latchPinS   = 3;
 | 
				
			||||||
 | 
					const int dataPinS    = 2;
 | 
				
			||||||
 | 
					//Pins für Minuten-Schieberegister
 | 
				
			||||||
 | 
					const int clockPinM   = 7;
 | 
				
			||||||
 | 
					const int latchPinM   = 6;
 | 
				
			||||||
 | 
					const int dataPinM    = 5;
 | 
				
			||||||
 | 
					//Pins für Stunden-Schieberegister
 | 
				
			||||||
 | 
					const int clockPinH   = 10;
 | 
				
			||||||
 | 
					const int latchPinH   = 9;
 | 
				
			||||||
 | 
					const int dataPinH    = 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const int tickled = 13;
 | 
				
			||||||
 | 
					const int taster = 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Variablen
 | 
				
			||||||
 | 
					long prevMillis = 0;
 | 
				
			||||||
 | 
					long interval   = 500;
 | 
				
			||||||
 | 
					Time t;
 | 
				
			||||||
 | 
					int stunden;
 | 
				
			||||||
 | 
					int minuten;
 | 
				
			||||||
 | 
					int sekunden;
 | 
				
			||||||
 | 
					int tag;
 | 
				
			||||||
 | 
					int monat;
 | 
				
			||||||
 | 
					int wochentag;
 | 
				
			||||||
 | 
					int temp;
 | 
				
			||||||
 | 
					int halbesekunde = 0;
 | 
				
			||||||
 | 
					int modus = 1;
 | 
				
			||||||
 | 
					int modustimer = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void setup(){
 | 
				
			||||||
 | 
					  //Outputpins
 | 
				
			||||||
 | 
					  pinMode(clockPinS, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(dataPinS,  OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(latchPinS, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(clockPinM, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(dataPinM,  OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(latchPinM, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(clockPinH, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(dataPinH,  OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(latchPinH, OUTPUT);
 | 
				
			||||||
 | 
					  pinMode(tickled, OUTPUT);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //Inputpin
 | 
				
			||||||
 | 
					  pinMode(taster, INPUT_PULLUP);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //RTC
 | 
				
			||||||
 | 
					  rtc.begin();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Nachfolgende Linien zur Zeiteinstellung unkommentieren
 | 
				
			||||||
 | 
					  //rtc.setDOW(2);                // Wochentag einstellen -> 1=Montag, 2=Dienstag, ...
 | 
				
			||||||
 | 
					  //rtc.setTime(16, 58, 00);     // Uhrzeit einstellen (Stunde, Minute, Sekunde)
 | 
				
			||||||
 | 
					  //rtc.setDate(02, 04, 2019);   // Datum einstellen (Tag, Monat, Jahr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //für Debugging un-kommentieren
 | 
				
			||||||
 | 
					  //Serial.begin(9600);
 | 
				
			||||||
 | 
					} //Ende von setup()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void loop(){
 | 
				
			||||||
 | 
					  /*if (digitalRead(addhour) == LOW){ //falls Minuten erhöht werden sollen
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					    minutes += 1;
 | 
				
			||||||
 | 
					    if (minutes > 58){
 | 
				
			||||||
 | 
					      minutes = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Serial.println("Minute++");
 | 
				
			||||||
 | 
					    while(digitalRead(2) == LOW){
 | 
				
			||||||
 | 
					      delay(10);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (digitalRead(taster) == LOW){
 | 
				
			||||||
 | 
					    modus++;
 | 
				
			||||||
 | 
					    modustimer = 0;
 | 
				
			||||||
 | 
					    if (modus == 4){
 | 
				
			||||||
 | 
					      modus = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    while(digitalRead(taster) == LOW){}
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(modustimer >= 10){
 | 
				
			||||||
 | 
					    modus = 1;
 | 
				
			||||||
 | 
					    modustimer = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					   unsigned long currentMillis = millis();
 | 
				
			||||||
 | 
					   if (currentMillis - prevMillis > interval) {
 | 
				
			||||||
 | 
					     prevMillis = currentMillis;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     if(halbesekunde == 1){
 | 
				
			||||||
 | 
					       if (modus == 1){
 | 
				
			||||||
 | 
					        t = rtc.getTime();
 | 
				
			||||||
 | 
					        stunden = t.hour, DEC;
 | 
				
			||||||
 | 
					        minuten = t.min, DEC;
 | 
				
			||||||
 | 
					        sekunden = t.sec, DEC;
 | 
				
			||||||
 | 
					        digitalWrite(tickled, HIGH);
 | 
				
			||||||
 | 
					        displayTime();
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					       else if (modus == 2){
 | 
				
			||||||
 | 
					        t = rtc.getTime();
 | 
				
			||||||
 | 
					        tag = t.date, DEC;
 | 
				
			||||||
 | 
					        monat = t.mon, DEC;
 | 
				
			||||||
 | 
					        wochentag = t.dow, DEC;
 | 
				
			||||||
 | 
					        modustimer++;
 | 
				
			||||||
 | 
					        displayDate();
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					       else if (modus == 3){
 | 
				
			||||||
 | 
					        temp = int(rtc.getTemp());
 | 
				
			||||||
 | 
					        modustimer++;
 | 
				
			||||||
 | 
					        displayTemp();
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					       //für Debugging un-kommentieren
 | 
				
			||||||
 | 
					       /*Serial.println("");
 | 
				
			||||||
 | 
					       Serial.println("Zeit:"); //für debugging
 | 
				
			||||||
 | 
					       Serial.print(String(stunden));
 | 
				
			||||||
 | 
					       Serial.print(":");
 | 
				
			||||||
 | 
					       Serial.print(String(minuten));
 | 
				
			||||||
 | 
					       Serial.print(":");
 | 
				
			||||||
 | 
					       Serial.print(String(sekunden));
 | 
				
			||||||
 | 
					       //*/
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					       halbesekunde = 0;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					     else{
 | 
				
			||||||
 | 
					       digitalWrite(tickled, LOW);
 | 
				
			||||||
 | 
					       halbesekunde = 1;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					} //Ende von loop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void displayTime(){ //Sendet die Zeit zu den Shiftregistern
 | 
				
			||||||
 | 
					    //Sekunden
 | 
				
			||||||
 | 
					    digitalWrite(latchPinS, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinS, clockPinS, MSBFIRST, sekunden);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinS, HIGH);
 | 
				
			||||||
 | 
					    //Minuten
 | 
				
			||||||
 | 
					    digitalWrite(latchPinM, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinM, clockPinM, MSBFIRST, minuten);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinM, HIGH);
 | 
				
			||||||
 | 
					    //Stunden
 | 
				
			||||||
 | 
					    digitalWrite(latchPinH, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinH, clockPinH, MSBFIRST, stunden);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinH, HIGH);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void displayDate(){ //Sendet Datum zu den Shiftregistern
 | 
				
			||||||
 | 
					    digitalWrite(latchPinS, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinS, clockPinS, MSBFIRST, wochentag);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinS, HIGH);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinM, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinM, clockPinM, MSBFIRST, monat);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinM, HIGH);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinH, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinH, clockPinH, MSBFIRST, tag);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinH, HIGH);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void displayTemp(){ //Sendet Temperatur zu den Shiftregistern
 | 
				
			||||||
 | 
					    digitalWrite(latchPinS, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinS, clockPinS, MSBFIRST, temp);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinS, HIGH);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinM, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinM, clockPinM, MSBFIRST, 0);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinM, HIGH);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinH, LOW);
 | 
				
			||||||
 | 
					    shiftOut(dataPinH, clockPinH, MSBFIRST, 0);
 | 
				
			||||||
 | 
					    digitalWrite(latchPinH, HIGH);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										447
									
								
								software_binaeruhr/src/DS3231.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								software_binaeruhr/src/DS3231.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,447 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  DS3231.cpp - Arduino/chipKit library support for the DS3231 I2C Real-Time Clock
 | 
				
			||||||
 | 
					  Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  This library has been made to easily interface and use the DS3231 RTC with
 | 
				
			||||||
 | 
					  an Arduino or chipKit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  You can find the latest version of the library at 
 | 
				
			||||||
 | 
					  http://www.RinkyDinkElectronics.com/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					  modify it under the terms of the CC BY-NC-SA 3.0 license.
 | 
				
			||||||
 | 
					  Please see the included documents for further information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Commercial use of this library requires you to buy a license that
 | 
				
			||||||
 | 
					  will allow commercial use. This includes using the library,
 | 
				
			||||||
 | 
					  modified or not, as a tool to sell products.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The license applies to all part of the library including the 
 | 
				
			||||||
 | 
					  examples and tools supplied with the library.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include "DS3231.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Include hardware-specific functions for the correct MCU
 | 
				
			||||||
 | 
					#if defined(__AVR__)
 | 
				
			||||||
 | 
						#include "hardware/avr/HW_AVR.h"
 | 
				
			||||||
 | 
					#elif defined(__PIC32MX__)
 | 
				
			||||||
 | 
					  #include "hardware/pic32/HW_PIC32.h"
 | 
				
			||||||
 | 
					#elif defined(__arm__)
 | 
				
			||||||
 | 
						#include "hardware/arm/HW_ARM.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define REG_SEC		0x00
 | 
				
			||||||
 | 
					#define REG_MIN		0x01
 | 
				
			||||||
 | 
					#define REG_HOUR	0x02
 | 
				
			||||||
 | 
					#define REG_DOW		0x03
 | 
				
			||||||
 | 
					#define REG_DATE	0x04
 | 
				
			||||||
 | 
					#define REG_MON		0x05
 | 
				
			||||||
 | 
					#define REG_YEAR	0x06
 | 
				
			||||||
 | 
					#define REG_CON		0x0e
 | 
				
			||||||
 | 
					#define REG_STATUS	0x0f
 | 
				
			||||||
 | 
					#define REG_AGING	0x10
 | 
				
			||||||
 | 
					#define REG_TEMPM	0x11
 | 
				
			||||||
 | 
					#define REG_TEMPL	0x12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SEC_1970_TO_2000 946684800
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t dim[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Public */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Time::Time()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						this->year = 2014;
 | 
				
			||||||
 | 
						this->mon  = 1;
 | 
				
			||||||
 | 
						this->date = 1;
 | 
				
			||||||
 | 
						this->hour = 0;
 | 
				
			||||||
 | 
						this->min  = 0;
 | 
				
			||||||
 | 
						this->sec  = 0;
 | 
				
			||||||
 | 
						this->dow  = 3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DS3231::DS3231(uint8_t data_pin, uint8_t sclk_pin)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						_sda_pin = data_pin;
 | 
				
			||||||
 | 
						_scl_pin = sclk_pin;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Time DS3231::getTime()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Time t;
 | 
				
			||||||
 | 
						_burstRead();
 | 
				
			||||||
 | 
						t.sec	= _decode(_burstArray[0]);
 | 
				
			||||||
 | 
						t.min	= _decode(_burstArray[1]);
 | 
				
			||||||
 | 
						t.hour	= _decodeH(_burstArray[2]);
 | 
				
			||||||
 | 
						t.dow	= _burstArray[3];
 | 
				
			||||||
 | 
						t.date	= _decode(_burstArray[4]);
 | 
				
			||||||
 | 
						t.mon	= _decode(_burstArray[5]);
 | 
				
			||||||
 | 
						t.year	= _decodeY(_burstArray[6])+2000;
 | 
				
			||||||
 | 
						return t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::setTime(uint8_t hour, uint8_t min, uint8_t sec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (((hour>=0) && (hour<24)) && ((min>=0) && (min<60)) && ((sec>=0) && (sec<60)))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_writeRegister(REG_HOUR, _encode(hour));
 | 
				
			||||||
 | 
							_writeRegister(REG_MIN, _encode(min));
 | 
				
			||||||
 | 
							_writeRegister(REG_SEC, _encode(sec));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::setDate(uint8_t date, uint8_t mon, uint16_t year)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (((date>0) && (date<=31)) && ((mon>0) && (mon<=12)) && ((year>=2000) && (year<3000)))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							year -= 2000;
 | 
				
			||||||
 | 
							_writeRegister(REG_YEAR, _encode(year));
 | 
				
			||||||
 | 
							_writeRegister(REG_MON, _encode(mon));
 | 
				
			||||||
 | 
							_writeRegister(REG_DATE, _encode(date));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::setDOW()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int dow;
 | 
				
			||||||
 | 
						byte mArr[12] = {6,2,2,5,0,3,5,1,4,6,2,4};
 | 
				
			||||||
 | 
						Time _t = getTime();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
						dow = (_t.year % 100);
 | 
				
			||||||
 | 
						dow = dow*1.25;
 | 
				
			||||||
 | 
						dow += _t.date;
 | 
				
			||||||
 | 
						dow += mArr[_t.mon-1];
 | 
				
			||||||
 | 
						if (((_t.year % 4)==0) && (_t.mon<3))
 | 
				
			||||||
 | 
							dow -= 1;
 | 
				
			||||||
 | 
						while (dow>7)
 | 
				
			||||||
 | 
							dow -= 7;
 | 
				
			||||||
 | 
						_writeRegister(REG_DOW, dow);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::setDOW(uint8_t dow)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((dow>0) && (dow<8))
 | 
				
			||||||
 | 
							_writeRegister(REG_DOW, dow);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *DS3231::getTimeStr(uint8_t format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char output[] = "xxxxxxxx";
 | 
				
			||||||
 | 
						Time t;
 | 
				
			||||||
 | 
						t=getTime();
 | 
				
			||||||
 | 
						if (t.hour<10)
 | 
				
			||||||
 | 
							output[0]=48;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							output[0]=char((t.hour / 10)+48);
 | 
				
			||||||
 | 
						output[1]=char((t.hour % 10)+48);
 | 
				
			||||||
 | 
						output[2]=58;
 | 
				
			||||||
 | 
						if (t.min<10)
 | 
				
			||||||
 | 
							output[3]=48;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							output[3]=char((t.min / 10)+48);
 | 
				
			||||||
 | 
						output[4]=char((t.min % 10)+48);
 | 
				
			||||||
 | 
						output[5]=58;
 | 
				
			||||||
 | 
						if (format==FORMAT_SHORT)
 | 
				
			||||||
 | 
							output[5]=0;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						if (t.sec<10)
 | 
				
			||||||
 | 
							output[6]=48;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							output[6]=char((t.sec / 10)+48);
 | 
				
			||||||
 | 
						output[7]=char((t.sec % 10)+48);
 | 
				
			||||||
 | 
						output[8]=0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (char*)&output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *DS3231::getDateStr(uint8_t slformat, uint8_t eformat, char divider)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char output[] = "xxxxxxxxxx";
 | 
				
			||||||
 | 
						int yr, offset;
 | 
				
			||||||
 | 
						Time t;
 | 
				
			||||||
 | 
						t=getTime();
 | 
				
			||||||
 | 
						switch (eformat)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case FORMAT_LITTLEENDIAN:
 | 
				
			||||||
 | 
								if (t.date<10)
 | 
				
			||||||
 | 
									output[0]=48;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									output[0]=char((t.date / 10)+48);
 | 
				
			||||||
 | 
								output[1]=char((t.date % 10)+48);
 | 
				
			||||||
 | 
								output[2]=divider;
 | 
				
			||||||
 | 
								if (t.mon<10)
 | 
				
			||||||
 | 
									output[3]=48;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									output[3]=char((t.mon / 10)+48);
 | 
				
			||||||
 | 
								output[4]=char((t.mon % 10)+48);
 | 
				
			||||||
 | 
								output[5]=divider;
 | 
				
			||||||
 | 
								if (slformat==FORMAT_SHORT)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									yr=t.year-2000;
 | 
				
			||||||
 | 
									if (yr<10)
 | 
				
			||||||
 | 
										output[6]=48;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										output[6]=char((yr / 10)+48);
 | 
				
			||||||
 | 
									output[7]=char((yr % 10)+48);
 | 
				
			||||||
 | 
									output[8]=0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									yr=t.year;
 | 
				
			||||||
 | 
									output[6]=char((yr / 1000)+48);
 | 
				
			||||||
 | 
									output[7]=char(((yr % 1000) / 100)+48);
 | 
				
			||||||
 | 
									output[8]=char(((yr % 100) / 10)+48);
 | 
				
			||||||
 | 
									output[9]=char((yr % 10)+48);
 | 
				
			||||||
 | 
									output[10]=0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case FORMAT_BIGENDIAN:
 | 
				
			||||||
 | 
								if (slformat==FORMAT_SHORT)
 | 
				
			||||||
 | 
									offset=0;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									offset=2;
 | 
				
			||||||
 | 
								if (slformat==FORMAT_SHORT)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									yr=t.year-2000;
 | 
				
			||||||
 | 
									if (yr<10)
 | 
				
			||||||
 | 
										output[0]=48;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										output[0]=char((yr / 10)+48);
 | 
				
			||||||
 | 
									output[1]=char((yr % 10)+48);
 | 
				
			||||||
 | 
									output[2]=divider;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									yr=t.year;
 | 
				
			||||||
 | 
									output[0]=char((yr / 1000)+48);
 | 
				
			||||||
 | 
									output[1]=char(((yr % 1000) / 100)+48);
 | 
				
			||||||
 | 
									output[2]=char(((yr % 100) / 10)+48);
 | 
				
			||||||
 | 
									output[3]=char((yr % 10)+48);
 | 
				
			||||||
 | 
									output[4]=divider;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (t.mon<10)
 | 
				
			||||||
 | 
									output[3+offset]=48;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									output[3+offset]=char((t.mon / 10)+48);
 | 
				
			||||||
 | 
								output[4+offset]=char((t.mon % 10)+48);
 | 
				
			||||||
 | 
								output[5+offset]=divider;
 | 
				
			||||||
 | 
								if (t.date<10)
 | 
				
			||||||
 | 
									output[6+offset]=48;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									output[6+offset]=char((t.date / 10)+48);
 | 
				
			||||||
 | 
								output[7+offset]=char((t.date % 10)+48);
 | 
				
			||||||
 | 
								output[8+offset]=0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case FORMAT_MIDDLEENDIAN:
 | 
				
			||||||
 | 
								if (t.mon<10)
 | 
				
			||||||
 | 
									output[0]=48;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									output[0]=char((t.mon / 10)+48);
 | 
				
			||||||
 | 
								output[1]=char((t.mon % 10)+48);
 | 
				
			||||||
 | 
								output[2]=divider;
 | 
				
			||||||
 | 
								if (t.date<10)
 | 
				
			||||||
 | 
									output[3]=48;
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									output[3]=char((t.date / 10)+48);
 | 
				
			||||||
 | 
								output[4]=char((t.date % 10)+48);
 | 
				
			||||||
 | 
								output[5]=divider;
 | 
				
			||||||
 | 
								if (slformat==FORMAT_SHORT)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									yr=t.year-2000;
 | 
				
			||||||
 | 
									if (yr<10)
 | 
				
			||||||
 | 
										output[6]=48;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										output[6]=char((yr / 10)+48);
 | 
				
			||||||
 | 
									output[7]=char((yr % 10)+48);
 | 
				
			||||||
 | 
									output[8]=0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									yr=t.year;
 | 
				
			||||||
 | 
									output[6]=char((yr / 1000)+48);
 | 
				
			||||||
 | 
									output[7]=char(((yr % 1000) / 100)+48);
 | 
				
			||||||
 | 
									output[8]=char(((yr % 100) / 10)+48);
 | 
				
			||||||
 | 
									output[9]=char((yr % 10)+48);
 | 
				
			||||||
 | 
									output[10]=0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (char*)&output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *DS3231::getDOWStr(uint8_t format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *output = "xxxxxxxxxx";
 | 
				
			||||||
 | 
						char *daysLong[]  = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
 | 
				
			||||||
 | 
						char *daysShort[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
 | 
				
			||||||
 | 
						Time t;
 | 
				
			||||||
 | 
						t=getTime();
 | 
				
			||||||
 | 
						if (format == FORMAT_SHORT)
 | 
				
			||||||
 | 
							output = daysShort[t.dow-1];
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							output = daysLong[t.dow-1];
 | 
				
			||||||
 | 
						return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *DS3231::getMonthStr(uint8_t format)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *output= "xxxxxxxxx";
 | 
				
			||||||
 | 
						char *monthLong[]  = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
 | 
				
			||||||
 | 
						char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
 | 
				
			||||||
 | 
						Time t;
 | 
				
			||||||
 | 
						t=getTime();
 | 
				
			||||||
 | 
						if (format == FORMAT_SHORT)
 | 
				
			||||||
 | 
							output = monthShort[t.mon-1];
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							output = monthLong[t.mon-1];
 | 
				
			||||||
 | 
						return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long DS3231::getUnixTime(Time t)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint16_t	dc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dc = t.date;
 | 
				
			||||||
 | 
						for (uint8_t i = 0; i<(t.mon-1); i++)
 | 
				
			||||||
 | 
							dc += dim[i];
 | 
				
			||||||
 | 
						if ((t.mon > 2) && (((t.year-2000) % 4) == 0))
 | 
				
			||||||
 | 
							++dc;
 | 
				
			||||||
 | 
						dc = dc + (365 * (t.year-2000)) + (((t.year-2000) + 3) / 4) - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ((((((dc * 24L) + t.hour) * 60) + t.min) * 60) + t.sec) + SEC_1970_TO_2000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::enable32KHz(bool enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint8_t _reg = _readRegister(REG_STATUS);
 | 
				
			||||||
 | 
					  _reg &= ~(1 << 3);
 | 
				
			||||||
 | 
					  _reg |= (enable << 3);
 | 
				
			||||||
 | 
					  _writeRegister(REG_STATUS, _reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::setOutput(byte enable)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint8_t _reg = _readRegister(REG_CON);
 | 
				
			||||||
 | 
					  _reg &= ~(1 << 2);
 | 
				
			||||||
 | 
					  _reg |= (enable << 2);
 | 
				
			||||||
 | 
					  _writeRegister(REG_CON, _reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::setSQWRate(int rate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  uint8_t _reg = _readRegister(REG_CON);
 | 
				
			||||||
 | 
					  _reg &= ~(3 << 3);
 | 
				
			||||||
 | 
					  _reg |= (rate << 3);
 | 
				
			||||||
 | 
					  _writeRegister(REG_CON, _reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float DS3231::getTemp()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t _msb = _readRegister(REG_TEMPM);
 | 
				
			||||||
 | 
						uint8_t _lsb = _readRegister(REG_TEMPL);
 | 
				
			||||||
 | 
						return (float)_msb + ((_lsb >> 6) * 0.25f);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Private */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	DS3231::_sendStart(byte addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, OUTPUT);
 | 
				
			||||||
 | 
						digitalWrite(_sda_pin, HIGH);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, HIGH);
 | 
				
			||||||
 | 
						digitalWrite(_sda_pin, LOW);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
						shiftOut(_sda_pin, _scl_pin, MSBFIRST, addr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	DS3231::_sendStop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, OUTPUT);
 | 
				
			||||||
 | 
						digitalWrite(_sda_pin, LOW);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, HIGH);
 | 
				
			||||||
 | 
						digitalWrite(_sda_pin, HIGH);
 | 
				
			||||||
 | 
						pinMode(_sda_pin, INPUT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	DS3231::_sendNack()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, OUTPUT);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
						digitalWrite(_sda_pin, HIGH);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, HIGH);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
						pinMode(_sda_pin, INPUT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	DS3231::_sendAck()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, OUTPUT);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
						digitalWrite(_sda_pin, LOW);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, HIGH);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
						pinMode(_sda_pin, INPUT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	DS3231::_waitForAck()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, INPUT);
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, HIGH);
 | 
				
			||||||
 | 
						while (digitalRead(_sda_pin)==HIGH) {}
 | 
				
			||||||
 | 
						digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t DS3231::_readByte()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, INPUT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t value = 0;
 | 
				
			||||||
 | 
						uint8_t currentBit = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < 8; ++i)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							digitalWrite(_scl_pin, HIGH);
 | 
				
			||||||
 | 
							currentBit = digitalRead(_sda_pin);
 | 
				
			||||||
 | 
							value |= (currentBit << 7-i);
 | 
				
			||||||
 | 
							delayMicroseconds(1);
 | 
				
			||||||
 | 
							digitalWrite(_scl_pin, LOW);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_writeByte(uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pinMode(_sda_pin, OUTPUT);
 | 
				
			||||||
 | 
						shiftOut(_sda_pin, _scl_pin, MSBFIRST, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t	DS3231::_decode(uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t decoded = value & 127;
 | 
				
			||||||
 | 
						decoded = (decoded & 15) + 10 * ((decoded & (15 << 4)) >> 4);
 | 
				
			||||||
 | 
						return decoded;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t DS3231::_decodeH(uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (value & 128)
 | 
				
			||||||
 | 
					    value = (value & 15) + (12 * ((value & 32) >> 5));
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    value = (value & 15) + (10 * ((value & 48) >> 4));
 | 
				
			||||||
 | 
					  return value;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t	DS3231::_decodeY(uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t decoded = (value & 15) + 10 * ((value & (15 << 4)) >> 4);
 | 
				
			||||||
 | 
						return decoded;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t DS3231::_encode(uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t encoded = ((value / 10) << 4) + (value % 10);
 | 
				
			||||||
 | 
						return encoded;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										123
									
								
								software_binaeruhr/src/DS3231.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								software_binaeruhr/src/DS3231.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					  DS3231.cpp - Arduino/chipKit library support for the DS3231 I2C Real-Time Clock
 | 
				
			||||||
 | 
					  Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  This library has been made to easily interface and use the DS3231 RTC with
 | 
				
			||||||
 | 
					  an Arduino or chipKit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  You can find the latest version of the library at 
 | 
				
			||||||
 | 
					  http://www.RinkyDinkElectronics.com/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  This library is free software; you can redistribute it and/or
 | 
				
			||||||
 | 
					  modify it under the terms of the CC BY-NC-SA 3.0 license.
 | 
				
			||||||
 | 
					  Please see the included documents for further information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Commercial use of this library requires you to buy a license that
 | 
				
			||||||
 | 
					  will allow commercial use. This includes using the library,
 | 
				
			||||||
 | 
					  modified or not, as a tool to sell products.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The license applies to all part of the library including the 
 | 
				
			||||||
 | 
					  examples and tools supplied with the library.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#ifndef DS3231_h
 | 
				
			||||||
 | 
					#define DS3231_h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__AVR__)
 | 
				
			||||||
 | 
						#include "Arduino.h"
 | 
				
			||||||
 | 
						#include "hardware/avr/HW_AVR_defines.h"
 | 
				
			||||||
 | 
					#elif defined(__PIC32MX__)
 | 
				
			||||||
 | 
						#include "WProgram.h"
 | 
				
			||||||
 | 
						#include "hardware/pic32/HW_PIC32_defines.h"
 | 
				
			||||||
 | 
					#elif defined(__arm__)
 | 
				
			||||||
 | 
						#include "Arduino.h"
 | 
				
			||||||
 | 
						#include "hardware/arm/HW_ARM_defines.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DS3231_ADDR_R	0xD1
 | 
				
			||||||
 | 
					#define DS3231_ADDR_W	0xD0
 | 
				
			||||||
 | 
					#define DS3231_ADDR		0x68
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FORMAT_SHORT	1
 | 
				
			||||||
 | 
					#define FORMAT_LONG		2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FORMAT_LITTLEENDIAN	1
 | 
				
			||||||
 | 
					#define FORMAT_BIGENDIAN	2
 | 
				
			||||||
 | 
					#define FORMAT_MIDDLEENDIAN	3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MONDAY		1
 | 
				
			||||||
 | 
					#define TUESDAY		2
 | 
				
			||||||
 | 
					#define WEDNESDAY	3
 | 
				
			||||||
 | 
					#define THURSDAY	4
 | 
				
			||||||
 | 
					#define FRIDAY		5
 | 
				
			||||||
 | 
					#define SATURDAY	6
 | 
				
			||||||
 | 
					#define SUNDAY		7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SQW_RATE_1		0
 | 
				
			||||||
 | 
					#define SQW_RATE_1K		1
 | 
				
			||||||
 | 
					#define SQW_RATE_4K		2
 | 
				
			||||||
 | 
					#define SQW_RATE_8K		3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OUTPUT_SQW		0
 | 
				
			||||||
 | 
					#define OUTPUT_INT		1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Time
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						uint8_t		hour;
 | 
				
			||||||
 | 
						uint8_t		min;
 | 
				
			||||||
 | 
						uint8_t		sec;
 | 
				
			||||||
 | 
						uint8_t		date;
 | 
				
			||||||
 | 
						uint8_t		mon;
 | 
				
			||||||
 | 
						uint16_t	year;
 | 
				
			||||||
 | 
						uint8_t		dow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Time();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DS3231
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
							DS3231(uint8_t data_pin, uint8_t sclk_pin);
 | 
				
			||||||
 | 
							void	begin();
 | 
				
			||||||
 | 
							Time	getTime();
 | 
				
			||||||
 | 
							void	setTime(uint8_t hour, uint8_t min, uint8_t sec);
 | 
				
			||||||
 | 
							void	setDate(uint8_t date, uint8_t mon, uint16_t year);
 | 
				
			||||||
 | 
							void	setDOW();
 | 
				
			||||||
 | 
							void	setDOW(uint8_t dow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							char	*getTimeStr(uint8_t format=FORMAT_LONG);
 | 
				
			||||||
 | 
							char	*getDateStr(uint8_t slformat=FORMAT_LONG, uint8_t eformat=FORMAT_LITTLEENDIAN, char divider='.');
 | 
				
			||||||
 | 
							char	*getDOWStr(uint8_t format=FORMAT_LONG);
 | 
				
			||||||
 | 
							char	*getMonthStr(uint8_t format=FORMAT_LONG);
 | 
				
			||||||
 | 
							long	getUnixTime(Time t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void	enable32KHz(bool enable);
 | 
				
			||||||
 | 
							void	setOutput(byte enable);
 | 
				
			||||||
 | 
							void	setSQWRate(int rate);
 | 
				
			||||||
 | 
							float	getTemp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
							uint8_t _scl_pin;
 | 
				
			||||||
 | 
							uint8_t _sda_pin;
 | 
				
			||||||
 | 
							uint8_t _burstArray[7];
 | 
				
			||||||
 | 
							boolean	_use_hw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void	_sendStart(byte addr);
 | 
				
			||||||
 | 
							void	_sendStop();
 | 
				
			||||||
 | 
							void	_sendAck();
 | 
				
			||||||
 | 
							void	_sendNack();
 | 
				
			||||||
 | 
							void	_waitForAck();
 | 
				
			||||||
 | 
							uint8_t	_readByte();
 | 
				
			||||||
 | 
							void	_writeByte(uint8_t value);
 | 
				
			||||||
 | 
							void	_burstRead();
 | 
				
			||||||
 | 
							uint8_t	_readRegister(uint8_t reg);
 | 
				
			||||||
 | 
							void 	_writeRegister(uint8_t reg, uint8_t value);
 | 
				
			||||||
 | 
							uint8_t	_decode(uint8_t value);
 | 
				
			||||||
 | 
							uint8_t	_decodeH(uint8_t value);
 | 
				
			||||||
 | 
							uint8_t	_decodeY(uint8_t value);
 | 
				
			||||||
 | 
							uint8_t	_encode(uint8_t vaule);
 | 
				
			||||||
 | 
					#if defined(__arm__)
 | 
				
			||||||
 | 
							Twi		*twi;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										154
									
								
								software_binaeruhr/src/hardware/arm/HW_ARM.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								software_binaeruhr/src/hardware/arm/HW_ARM.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					void DS3231::begin()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						_use_hw = false;
 | 
				
			||||||
 | 
						if ((_sda_pin == SDA) and (_scl_pin == SCL))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_use_hw = true;
 | 
				
			||||||
 | 
							twi = TWI1;
 | 
				
			||||||
 | 
							pmc_enable_periph_clk(WIRE_INTERFACE_ID);
 | 
				
			||||||
 | 
							PIO_Configure(g_APinDescription[PIN_WIRE_SDA].pPort, g_APinDescription[PIN_WIRE_SDA].ulPinType, g_APinDescription[PIN_WIRE_SDA].ulPin, g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
 | 
				
			||||||
 | 
							PIO_Configure(g_APinDescription[PIN_WIRE_SCL].pPort, g_APinDescription[PIN_WIRE_SCL].ulPinType, g_APinDescription[PIN_WIRE_SCL].ulPin, g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);
 | 
				
			||||||
 | 
							NVIC_DisableIRQ(TWI1_IRQn);
 | 
				
			||||||
 | 
							NVIC_ClearPendingIRQ(TWI1_IRQn);
 | 
				
			||||||
 | 
							NVIC_SetPriority(TWI1_IRQn, 0);
 | 
				
			||||||
 | 
							NVIC_EnableIRQ(TWI1_IRQn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if ((_sda_pin == SDA1) and (_scl_pin == SCL1))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_use_hw = true;
 | 
				
			||||||
 | 
							twi = TWI0;
 | 
				
			||||||
 | 
							pmc_enable_periph_clk(WIRE1_INTERFACE_ID);
 | 
				
			||||||
 | 
							PIO_Configure(g_APinDescription[PIN_WIRE1_SDA].pPort, g_APinDescription[PIN_WIRE1_SDA].ulPinType, g_APinDescription[PIN_WIRE1_SDA].ulPin, g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration);
 | 
				
			||||||
 | 
							PIO_Configure(g_APinDescription[PIN_WIRE1_SCL].pPort, g_APinDescription[PIN_WIRE1_SCL].ulPinType, g_APinDescription[PIN_WIRE1_SCL].ulPin, g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration);
 | 
				
			||||||
 | 
							NVIC_DisableIRQ(TWI0_IRQn);
 | 
				
			||||||
 | 
							NVIC_ClearPendingIRQ(TWI0_IRQn);
 | 
				
			||||||
 | 
							NVIC_SetPriority(TWI0_IRQn, 0);
 | 
				
			||||||
 | 
							NVIC_EnableIRQ(TWI0_IRQn);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// activate internal pullups for twi.
 | 
				
			||||||
 | 
							digitalWrite(SDA, 1);
 | 
				
			||||||
 | 
							digitalWrite(SCL, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Reset the TWI
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_SWRST;
 | 
				
			||||||
 | 
							// TWI Slave Mode Disabled, TWI Master Mode Disabled.
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_SVDIS;
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_MSDIS;
 | 
				
			||||||
 | 
							// Set TWI Speed
 | 
				
			||||||
 | 
							twi->TWI_CWGR = (TWI_DIV << 16) | (TWI_SPEED << 8) | TWI_SPEED;
 | 
				
			||||||
 | 
							// Set master mode
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_MSEN;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							pinMode(_scl_pin, OUTPUT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_burstRead()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Set slave address and number of internal address bytes.
 | 
				
			||||||
 | 
							twi->TWI_MMR = (1 << 8) | TWI_MMR_MREAD | (DS3231_ADDR << 16);
 | 
				
			||||||
 | 
							// Set internal address bytes
 | 
				
			||||||
 | 
							twi->TWI_IADR = 0;
 | 
				
			||||||
 | 
							// Send START condition
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_START;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (int i=0; i<6; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								while ((twi->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								_burstArray[i] = twi->TWI_RHR;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_STOP;
 | 
				
			||||||
 | 
							while ((twi->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY) {};
 | 
				
			||||||
 | 
							_burstArray[6] = twi->TWI_RHR;
 | 
				
			||||||
 | 
							while ((twi->TWI_SR & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(0);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_R);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (int i=0; i<7; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								_burstArray[i] = _readByte();
 | 
				
			||||||
 | 
								if (i<6)
 | 
				
			||||||
 | 
									_sendAck();
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									_sendNack();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t DS3231::_readRegister(uint8_t reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t	readValue=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Set slave address and number of internal address bytes.
 | 
				
			||||||
 | 
							twi->TWI_MMR = (1 << 8) | TWI_MMR_MREAD | (DS3231_ADDR << 16);
 | 
				
			||||||
 | 
							// Set internal address bytes
 | 
				
			||||||
 | 
							twi->TWI_IADR = reg;
 | 
				
			||||||
 | 
							// Send START and STOP condition to read a single byte
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_START | TWI_CR_STOP;
 | 
				
			||||||
 | 
							while ((twi->TWI_SR & TWI_SR_RXRDY) != TWI_SR_RXRDY) {};
 | 
				
			||||||
 | 
							readValue = twi->TWI_RHR;
 | 
				
			||||||
 | 
							while ((twi->TWI_SR & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(reg);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_R);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							readValue = _readByte();
 | 
				
			||||||
 | 
							_sendNack();
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return readValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_writeRegister(uint8_t reg, uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Set slave address and number of internal address bytes.
 | 
				
			||||||
 | 
							twi->TWI_MMR = (1 << 8) | (DS3231_ADDR << 16);
 | 
				
			||||||
 | 
							// Set internal address bytes
 | 
				
			||||||
 | 
							twi->TWI_IADR = reg;
 | 
				
			||||||
 | 
							// Send a single byte to start transfer
 | 
				
			||||||
 | 
							twi->TWI_THR = value;
 | 
				
			||||||
 | 
							while ((twi->TWI_SR & TWI_SR_TXRDY) != TWI_SR_TXRDY) {};
 | 
				
			||||||
 | 
							// Send STOP condition
 | 
				
			||||||
 | 
							twi->TWI_CR = TWI_CR_STOP;
 | 
				
			||||||
 | 
							while ((twi->TWI_SR & TWI_SR_TXCOMP) != TWI_SR_TXCOMP) {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(reg);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(value);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								software_binaeruhr/src/hardware/arm/HW_ARM_defines.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								software_binaeruhr/src/hardware/arm/HW_ARM_defines.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					// *** Hardwarespecific defines ***
 | 
				
			||||||
 | 
					#define SDA		20
 | 
				
			||||||
 | 
					#define SCL		21
 | 
				
			||||||
 | 
					#define SDA1	70
 | 
				
			||||||
 | 
					#define SCL1	71
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TWI_SPEED		TWI_SPEED_400k	// Set default TWI Speed
 | 
				
			||||||
 | 
					#define TWI_SPEED_100k	208
 | 
				
			||||||
 | 
					#define TWI_SPEED_400k	101
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TWI_DIV			TWI_DIV_400k	// Set divider for TWI Speed (must match TWI_SPEED setting)
 | 
				
			||||||
 | 
					#define TWI_DIV_100k	1
 | 
				
			||||||
 | 
					#define TWI_DIV_400k	0
 | 
				
			||||||
							
								
								
									
										153
									
								
								software_binaeruhr/src/hardware/avr/HW_AVR.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								software_binaeruhr/src/hardware/avr/HW_AVR.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,153 @@
 | 
				
			|||||||
 | 
					void DS3231::begin()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((_sda_pin == SDA) and (_scl_pin == SCL))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_use_hw = true;
 | 
				
			||||||
 | 
							// activate internal pullups for twi.
 | 
				
			||||||
 | 
							digitalWrite(SDA, HIGH);
 | 
				
			||||||
 | 
							digitalWrite(SCL, HIGH);
 | 
				
			||||||
 | 
							//delay(1);  // Workaround for a linker bug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// initialize twi prescaler and bit rate
 | 
				
			||||||
 | 
							cbi(TWSR, TWPS0);
 | 
				
			||||||
 | 
							cbi(TWSR, TWPS1);
 | 
				
			||||||
 | 
							TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// enable twi module, acks, and twi interrupt
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWIE)/* | _BV(TWEA)*/;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_use_hw = false;
 | 
				
			||||||
 | 
							pinMode(_scl_pin, OUTPUT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_burstRead()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Send start address
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);						// Send START
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = DS3231_ADDR_W;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = 0;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Read data starting from start address
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);						// Send rep. START
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = DS3231_ADDR_R;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							for (int i=0; i<7; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);								// Send ACK and clear TWINT to proceed
 | 
				
			||||||
 | 
								while ((TWCR & _BV(TWINT)) == 0) {};									// Wait for TWI to be ready
 | 
				
			||||||
 | 
								_burstArray[i] = TWDR;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT);												// Send NACK and clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN)| _BV(TWINT) | _BV(TWSTO);									// Send STOP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(0);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_R);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (int i=0; i<7; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								_burstArray[i] = _readByte();
 | 
				
			||||||
 | 
								if (i<6)
 | 
				
			||||||
 | 
									_sendAck();
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									_sendNack();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t DS3231::_readRegister(uint8_t reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t	readValue=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Send start address
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);						// Send START
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = DS3231_ADDR_W;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = reg;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Read data starting from start address
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);						// Send rep. START
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = DS3231_ADDR_R;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Send ACK and clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							readValue = TWDR;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT);												// Send NACK and clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN)| _BV(TWINT) | _BV(TWSTO);									// Send STOP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(reg);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_R);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							readValue = _readByte();
 | 
				
			||||||
 | 
							_sendNack();
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return readValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_writeRegister(uint8_t reg, uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Send start address
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA);						// Send START
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = DS3231_ADDR_W;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = reg;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
							TWDR = value;
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA);									// Clear TWINT to proceed
 | 
				
			||||||
 | 
							while ((TWCR & _BV(TWINT)) == 0) {};										// Wait for TWI to be ready
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TWCR = _BV(TWEN)| _BV(TWINT) | _BV(TWSTO);									// Send STOP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(reg);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(value);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								software_binaeruhr/src/hardware/avr/HW_AVR_defines.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								software_binaeruhr/src/hardware/avr/HW_AVR_defines.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					// *** Hardwarespecific defines ***
 | 
				
			||||||
 | 
					#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TWI_FREQ
 | 
				
			||||||
 | 
						#define TWI_FREQ 400000L
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										192
									
								
								software_binaeruhr/src/hardware/pic32/HW_PIC32.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								software_binaeruhr/src/hardware/pic32/HW_PIC32.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
				
			|||||||
 | 
					inline void _waitForIdleBus() { while (I2C1CON & 0x1f) {} }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::begin()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((_sda_pin == SDA) and (_scl_pin == SCL))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint32_t	tpgd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_use_hw = true;
 | 
				
			||||||
 | 
							pinMode(SDA, OUTPUT);
 | 
				
			||||||
 | 
							digitalWrite(SDA, HIGH);
 | 
				
			||||||
 | 
							IFS0CLR = 0xE0000000;									// Clear Interrupt Flag
 | 
				
			||||||
 | 
							IEC0CLR = 0xE0000000;									// Disable Interrupt
 | 
				
			||||||
 | 
							I2C1CONCLR = (1 << _I2CCON_ON);							// Disable I2C interface
 | 
				
			||||||
 | 
							tpgd = ((F_CPU / 8) * 104) / 125000000;
 | 
				
			||||||
 | 
							I2C1BRG = (F_CPU / (2 * TWI_FREQ) - tpgd) - 2;			// Set I2C Speed
 | 
				
			||||||
 | 
							I2C1ADD = DS3231_ADDR;									// Set I2C device address
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_ON) | (1 << _I2CCON_STREN);	// Enable I2C Interface
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_use_hw = false;
 | 
				
			||||||
 | 
							pinMode(_scl_pin, OUTPUT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_burstRead()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_waitForIdleBus();									// Wait for I2C bus to be Idle before starting
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_SEN);					// Send start condition
 | 
				
			||||||
 | 
							if (I2C1STAT & (1 << _I2CSTAT_BCL)) { return; }		// Check if there is a bus collision
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_SEN)) {}				// Wait for start condition to finish
 | 
				
			||||||
 | 
							I2C1TRN = (DS3231_ADDR<<1);							// Send device Write address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_IWCOL))			// Check if there is a Write collision
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								I2C1STATCLR = (1 << _I2CSTAT_IWCOL);			// Clear Write collision flag
 | 
				
			||||||
 | 
								I2C1TRN = (DS3231_ADDR<<1);						// Retry send device Write address
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							I2C1TRN = 0;										// Send the register address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							_waitForIdleBus();									// Wait for I2C bus to be Idle before starting
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_RSEN);					// Send start condition
 | 
				
			||||||
 | 
							if (I2C1STAT & (1 << _I2CSTAT_BCL)) { return; }		// Check if there is a bus collision
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_RSEN)) {}			// Wait for start condition to finish
 | 
				
			||||||
 | 
							I2C1TRN = (DS3231_ADDR<<1) | 1;						// Send device Read address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_IWCOL))			// Check if there is a Write collision
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								I2C1STATCLR = (1 << _I2CSTAT_IWCOL);			// Clear Write collision flag
 | 
				
			||||||
 | 
								I2C1TRN = (DS3231_ADDR<<1) | 1;					// Retry send device Read address
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							byte dummy = I2C1RCV;								// Clear _I2CSTAT_RBF (Receive Buffer Full)
 | 
				
			||||||
 | 
							for (int i=0; i<7; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								_waitForIdleBus();								// Wait for I2C bus to be Idle before continuing
 | 
				
			||||||
 | 
								I2C1CONSET = (1 << _I2CCON_RCEN);				// Set RCEN to start receive
 | 
				
			||||||
 | 
								while (I2C1CON & (1 << _I2CCON_RCEN)) {}		// Wait for Receive operation to finish
 | 
				
			||||||
 | 
								while (!(I2C1STAT & (1 << _I2CSTAT_RBF))) {}	// Wait for Receive Buffer Full
 | 
				
			||||||
 | 
								_burstArray[i] = I2C1RCV;						// Read data
 | 
				
			||||||
 | 
								if (i == 6)
 | 
				
			||||||
 | 
									I2C1CONSET = (1 << _I2CCON_ACKDT);			// Prepare to send NACK
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									I2C1CONCLR = (1 << _I2CCON_ACKDT);			// Prepare to send ACK
 | 
				
			||||||
 | 
								I2C1CONSET = (1 << _I2CCON_ACKEN);				// Send ACK/NACK
 | 
				
			||||||
 | 
								while (I2C1CON & (1 << _I2CCON_ACKEN)) {}		// Wait for ACK/NACK send to finish
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_PEN);					// Send stop condition
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_PEN)) {}				// Wait for stop condition to finish
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(0);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_R);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (int i=0; i<7; i++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								_burstArray[i] = _readByte();
 | 
				
			||||||
 | 
								if (i<6)
 | 
				
			||||||
 | 
									_sendAck();
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									_sendNack();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t DS3231::_readRegister(uint8_t reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t	readValue=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_waitForIdleBus();									// Wait for I2C bus to be Idle before starting
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_SEN);					// Send start condition
 | 
				
			||||||
 | 
							if (I2C1STAT & (1 << _I2CSTAT_BCL)) { return 0xff; }// Check if there is a bus collision
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_SEN)) {}				// Wait for start condition to finish
 | 
				
			||||||
 | 
							I2C1TRN = (DS3231_ADDR<<1);							// Send device Write address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_IWCOL))			// Check if there is a Write collision
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								I2C1STATCLR = (1 << _I2CSTAT_IWCOL);			// Clear Write collision flag
 | 
				
			||||||
 | 
								I2C1TRN = (DS3231_ADDR<<1);						// Retry send device Write address
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							I2C1TRN = reg;										// Send the register address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							_waitForIdleBus();									// Wait for I2C bus to be Idle before starting
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_RSEN);					// Send start condition
 | 
				
			||||||
 | 
							if (I2C1STAT & (1 << _I2CSTAT_BCL)) { return 0xff; }// Check if there is a bus collision
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_RSEN)) {}			// Wait for start condition to finish
 | 
				
			||||||
 | 
							I2C1TRN = (DS3231_ADDR<<1) | 1;						// Send device Read address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_IWCOL))			// Check if there is a Write collision
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								I2C1STATCLR = (1 << _I2CSTAT_IWCOL);			// Clear Write collision flag
 | 
				
			||||||
 | 
								I2C1TRN = (DS3231_ADDR<<1) | 1;					// Retry send device Read address
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							byte dummy = I2C1RCV;								// Clear _I2CSTAT_RBF (Receive Buffer Full)
 | 
				
			||||||
 | 
							_waitForIdleBus();									// Wait for I2C bus to be Idle before continuing
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_RCEN);					// Set RCEN to start receive
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_RCEN)) {}			// Wait for Receive operation to finish
 | 
				
			||||||
 | 
							while (!(I2C1STAT & (1 << _I2CSTAT_RBF))) {}		// Wait for Receive Buffer Full
 | 
				
			||||||
 | 
							readValue = I2C1RCV;								// Read data
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_ACKDT);					// Prepare to send NACK
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_ACKEN);					// Send NACK
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_ACKEN)) {}			// Wait for NACK send to finish
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_PEN);					// Send stop condition
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_PEN)) {}				// Wait for stop condition to finish
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(reg);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_R);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							readValue = _readByte();
 | 
				
			||||||
 | 
							_sendNack();
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return readValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DS3231::_writeRegister(uint8_t reg, uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (_use_hw)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_waitForIdleBus();									// Wait for I2C bus to be Idle before starting
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_SEN);					// Send start condition
 | 
				
			||||||
 | 
							if (I2C1STAT & (1 << _I2CSTAT_BCL)) { return; }		// Check if there is a bus collision
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_SEN)) {}				// Wait for start condition to finish
 | 
				
			||||||
 | 
							I2C1TRN = (DS3231_ADDR<<1);							// Send device Write address
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_IWCOL))			// Check if there is a Write collision
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								I2C1STATCLR = (1 << _I2CSTAT_IWCOL);			// Clear Write collision flag
 | 
				
			||||||
 | 
								I2C1TRN = (DS3231_ADDR<<1);						// Retry send device Write address
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							I2C1TRN = reg;										// Send the 1st data byte
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							I2C1TRN = value;									// Send the 2nd data byte
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_TRSTAT)) {}		// Wait for transmit to finish
 | 
				
			||||||
 | 
							while (I2C1STAT & (1 << _I2CSTAT_ACKSTAT)) {}		// Wait for ACK
 | 
				
			||||||
 | 
							I2C1CONSET = (1 << _I2CCON_PEN);					// Send stop condition
 | 
				
			||||||
 | 
							while (I2C1CON & (1 << _I2CCON_PEN)) {}				// Wait for stop condition to finish
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_sendStart(DS3231_ADDR_W);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(reg);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_writeByte(value);
 | 
				
			||||||
 | 
							_waitForAck();
 | 
				
			||||||
 | 
							_sendStop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								software_binaeruhr/src/hardware/pic32/HW_PIC32_defines.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								software_binaeruhr/src/hardware/pic32/HW_PIC32_defines.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					// *** Hardwarespecific defines ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(_UP_MCU_)
 | 
				
			||||||
 | 
						#if defined(__32MX320F128H__)
 | 
				
			||||||
 | 
							#define SDA	18					// A4 (Remeber to set the jumper correctly)
 | 
				
			||||||
 | 
							#define SCL	19					// A5 (Remeber to set the jumper correctly)
 | 
				
			||||||
 | 
						#elif defined(__32MX340F512H__)
 | 
				
			||||||
 | 
							#define SDA	18					// A4 (Remeber to set the jumper correctly)
 | 
				
			||||||
 | 
							#define SCL	19					// A5 (Remeber to set the jumper correctly)
 | 
				
			||||||
 | 
						#elif defined(__32MX795F512L__)
 | 
				
			||||||
 | 
							#define SDA	20					// Digital 20
 | 
				
			||||||
 | 
							#define SCL	21					// Digital 21
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
							#error "Unsupported PIC32 MCU!"
 | 
				
			||||||
 | 
						#endif  
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TWI_FREQ
 | 
				
			||||||
 | 
						#define TWI_FREQ 400000L
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user