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:
		
							
								
								
									
										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