DS3231
DS3231.cpp@16:610f7091e0ac, 2021-05-08 (annotated)
- Committer:
- lukas_formanek
- Date:
- Sat May 08 16:13:55 2021 +0000
- Revision:
- 16:610f7091e0ac
- Parent:
- 15:bf11392ccaea
LoRa_Access_Point
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lukas_formanek | 15:bf11392ccaea | 1 | #include "DS3231.h" |
lukas_formanek | 15:bf11392ccaea | 2 | |
lukas_formanek | 15:bf11392ccaea | 3 | DS3231::DS3231(PinName sda, PinName scl) : i2c(sda, scl) |
lukas_formanek | 16:610f7091e0ac | 4 | { |
lukas_formanek | 16:610f7091e0ac | 5 | w_adrs = ((DS3231_I2C_ADRS << 1) | I2C_WRITE); |
lukas_formanek | 16:610f7091e0ac | 6 | r_adrs = ((DS3231_I2C_ADRS << 1) | I2C_READ); |
lukas_formanek | 16:610f7091e0ac | 7 | } |
lukas_formanek | 15:bf11392ccaea | 8 | |
lukas_formanek | 15:bf11392ccaea | 9 | |
lukas_formanek | 15:bf11392ccaea | 10 | // BCD to decimal conversion |
lukas_formanek | 15:bf11392ccaea | 11 | int DS3231::bcd2dec(int k) |
lukas_formanek | 15:bf11392ccaea | 12 | {return(((k&0xF0)>>4)*10+(k&0x0F));} |
lukas_formanek | 15:bf11392ccaea | 13 | |
lukas_formanek | 15:bf11392ccaea | 14 | |
lukas_formanek | 15:bf11392ccaea | 15 | // decimal to BCD conversion |
lukas_formanek | 15:bf11392ccaea | 16 | int DS3231::dec2bcd(int k) |
lukas_formanek | 15:bf11392ccaea | 17 | {return((k/10)*16+(k%10));} |
lukas_formanek | 15:bf11392ccaea | 18 | |
lukas_formanek | 15:bf11392ccaea | 19 | void DS3231::setI2Cfrequency(int frequency) |
lukas_formanek | 15:bf11392ccaea | 20 | {i2c.frequency(frequency); |
lukas_formanek | 15:bf11392ccaea | 21 | } |
lukas_formanek | 15:bf11392ccaea | 22 | |
lukas_formanek | 15:bf11392ccaea | 23 | // read temperature from DS3231 |
lukas_formanek | 15:bf11392ccaea | 24 | float DS3231::readTemp() |
lukas_formanek | 15:bf11392ccaea | 25 | {char buf[2]; |
lukas_formanek | 15:bf11392ccaea | 26 | buf[0]=DS3231_MSB_Temp; |
lukas_formanek | 15:bf11392ccaea | 27 | int w=i2c.write(DS3231_Address,buf,1); |
lukas_formanek | 15:bf11392ccaea | 28 | int r=i2c.read(DS3231_Address,buf,2); |
lukas_formanek | 15:bf11392ccaea | 29 | error=((w!=0)||(r!=0)); |
lukas_formanek | 15:bf11392ccaea | 30 | return(buf[0]+buf[1]/256.0);} |
lukas_formanek | 15:bf11392ccaea | 31 | |
lukas_formanek | 15:bf11392ccaea | 32 | // force temperatue conversion |
lukas_formanek | 15:bf11392ccaea | 33 | void DS3231::convertTemperature() |
lukas_formanek | 15:bf11392ccaea | 34 | {int Control=readRegister(DS3231_Control)|DS3231_bit_CONV; |
lukas_formanek | 15:bf11392ccaea | 35 | writeRegister(DS3231_Control,Control); |
lukas_formanek | 15:bf11392ccaea | 36 | } |
lukas_formanek | 15:bf11392ccaea | 37 | |
lukas_formanek | 15:bf11392ccaea | 38 | // decode time registers |
lukas_formanek | 15:bf11392ccaea | 39 | void DS3231::decodeTime(int regHours, int regMinutes, int regSeconds,int *Hours, int *Minutes, int *Seconds) |
lukas_formanek | 15:bf11392ccaea | 40 | {*Hours=bcd2dec(regHours); |
lukas_formanek | 15:bf11392ccaea | 41 | *Minutes=bcd2dec(regMinutes); |
lukas_formanek | 15:bf11392ccaea | 42 | *Seconds=bcd2dec(regSeconds); |
lukas_formanek | 15:bf11392ccaea | 43 | } |
lukas_formanek | 15:bf11392ccaea | 44 | |
lukas_formanek | 15:bf11392ccaea | 45 | |
lukas_formanek | 15:bf11392ccaea | 46 | // read time registers dand decode them to decimal |
lukas_formanek | 15:bf11392ccaea | 47 | void DS3231::readTime(int *hours, int *minutes, int *seconds) |
lukas_formanek | 15:bf11392ccaea | 48 | {char buf[3]; |
lukas_formanek | 15:bf11392ccaea | 49 | buf[0]=DS3231_Seconds; |
lukas_formanek | 15:bf11392ccaea | 50 | int w=i2c.write(DS3231_Address,buf,1); |
lukas_formanek | 15:bf11392ccaea | 51 | int r=i2c.read(DS3231_Address,buf,3); |
lukas_formanek | 15:bf11392ccaea | 52 | decodeTime(buf[2],buf[1],buf[0],hours,minutes,seconds); |
lukas_formanek | 15:bf11392ccaea | 53 | error=((w!=0)||(r!=0)); |
lukas_formanek | 15:bf11392ccaea | 54 | } |
lukas_formanek | 15:bf11392ccaea | 55 | |
lukas_formanek | 15:bf11392ccaea | 56 | // set time register |
lukas_formanek | 15:bf11392ccaea | 57 | void DS3231::setTime(int hours, int minutes, int seconds) |
lukas_formanek | 15:bf11392ccaea | 58 | {writeRegister(DS3231_Seconds,dec2bcd(seconds)); |
lukas_formanek | 15:bf11392ccaea | 59 | writeRegister(DS3231_Minutes,dec2bcd(minutes)); |
lukas_formanek | 15:bf11392ccaea | 60 | writeRegister(DS3231_Hours,dec2bcd(hours)); |
lukas_formanek | 15:bf11392ccaea | 61 | } |
lukas_formanek | 15:bf11392ccaea | 62 | |
lukas_formanek | 15:bf11392ccaea | 63 | // decode date registers |
lukas_formanek | 15:bf11392ccaea | 64 | void DS3231::decodeDate(int regDate,int regMonth, int regYear, int *date, int *month, int *year) |
lukas_formanek | 15:bf11392ccaea | 65 | {*date=bcd2dec(regDate); |
lukas_formanek | 15:bf11392ccaea | 66 | int century=regMonth&128; |
lukas_formanek | 15:bf11392ccaea | 67 | *month=bcd2dec(regMonth&127); |
lukas_formanek | 15:bf11392ccaea | 68 | *year=bcd2dec(regYear); |
lukas_formanek | 15:bf11392ccaea | 69 | if (century==0) // only XXth and XXIst centuries allowed |
lukas_formanek | 15:bf11392ccaea | 70 | {*year=*year+1900;} |
lukas_formanek | 15:bf11392ccaea | 71 | else |
lukas_formanek | 15:bf11392ccaea | 72 | {*year=*year+2000;} |
lukas_formanek | 15:bf11392ccaea | 73 | } |
lukas_formanek | 15:bf11392ccaea | 74 | |
lukas_formanek | 15:bf11392ccaea | 75 | // read date registers |
lukas_formanek | 15:bf11392ccaea | 76 | void DS3231::readDate(int *date, int *month, int *year) |
lukas_formanek | 15:bf11392ccaea | 77 | {char buf[3]; |
lukas_formanek | 15:bf11392ccaea | 78 | buf[0]=DS3231_Date; |
lukas_formanek | 15:bf11392ccaea | 79 | int w=i2c.write(DS3231_Address,buf,1); |
lukas_formanek | 15:bf11392ccaea | 80 | int r=i2c.read(DS3231_Address,buf,3); |
lukas_formanek | 15:bf11392ccaea | 81 | decodeDate(buf[0],buf[1],buf[2],date,month,year); |
lukas_formanek | 15:bf11392ccaea | 82 | error=((w!=0)||(r!=0)); |
lukas_formanek | 15:bf11392ccaea | 83 | } |
lukas_formanek | 15:bf11392ccaea | 84 | |
lukas_formanek | 15:bf11392ccaea | 85 | // set the date registers |
lukas_formanek | 15:bf11392ccaea | 86 | void DS3231::setDate(int dayOfWeek, int date, int month, int year) |
lukas_formanek | 15:bf11392ccaea | 87 | {writeRegister(DS3231_Date,dec2bcd(date)); |
lukas_formanek | 15:bf11392ccaea | 88 | writeRegister(DS3231_Day,dayOfWeek); |
lukas_formanek | 15:bf11392ccaea | 89 | int century=0; // only XXth and XXIst centuries allowed |
lukas_formanek | 15:bf11392ccaea | 90 | if (year<1900){year=1900;} |
lukas_formanek | 15:bf11392ccaea | 91 | if (year>2099){year=2099;} |
lukas_formanek | 15:bf11392ccaea | 92 | if (year<2000) |
lukas_formanek | 15:bf11392ccaea | 93 | {year=year-1900;} |
lukas_formanek | 15:bf11392ccaea | 94 | else |
lukas_formanek | 15:bf11392ccaea | 95 | {year=year-2000;century=1;} |
lukas_formanek | 15:bf11392ccaea | 96 | writeRegister(DS3231_Month_Century,dec2bcd(month)+128*century); |
lukas_formanek | 15:bf11392ccaea | 97 | writeRegister(DS3231_Year,dec2bcd(year)); |
lukas_formanek | 15:bf11392ccaea | 98 | } |
lukas_formanek | 15:bf11392ccaea | 99 | |
lukas_formanek | 15:bf11392ccaea | 100 | // read date and time registers |
lukas_formanek | 15:bf11392ccaea | 101 | void DS3231::readDateTime(int *dayOfWeek, int *date, int *month, int *year, int *hours, int *minutes, int *seconds) |
lukas_formanek | 15:bf11392ccaea | 102 | {char buf[7]; |
lukas_formanek | 15:bf11392ccaea | 103 | buf[0]=DS3231_Seconds; |
lukas_formanek | 15:bf11392ccaea | 104 | int w=i2c.write(DS3231_Address,buf,1); |
lukas_formanek | 15:bf11392ccaea | 105 | int r=i2c.read(DS3231_Address,buf,7); |
lukas_formanek | 15:bf11392ccaea | 106 | decodeTime(buf[2],buf[1],buf[0],hours,minutes,seconds); |
lukas_formanek | 15:bf11392ccaea | 107 | *dayOfWeek=buf[3]; |
lukas_formanek | 15:bf11392ccaea | 108 | decodeDate(buf[4],buf[5],buf[6],date,month,year); |
lukas_formanek | 15:bf11392ccaea | 109 | error=((w!=0)||(r!=0)); |
lukas_formanek | 15:bf11392ccaea | 110 | } |
lukas_formanek | 15:bf11392ccaea | 111 | |
lukas_formanek | 15:bf11392ccaea | 112 | // read a register |
lukas_formanek | 15:bf11392ccaea | 113 | int DS3231::readRegister(char reg) |
lukas_formanek | 15:bf11392ccaea | 114 | {char buf[1]; |
lukas_formanek | 15:bf11392ccaea | 115 | buf[0]=reg; |
lukas_formanek | 15:bf11392ccaea | 116 | int w=i2c.write(DS3231_Address,buf,1); |
lukas_formanek | 15:bf11392ccaea | 117 | int r=i2c.read(DS3231_Address,buf,1); |
lukas_formanek | 15:bf11392ccaea | 118 | error=((w!=0)||(r!=0)); |
lukas_formanek | 15:bf11392ccaea | 119 | return(buf[0]); |
lukas_formanek | 15:bf11392ccaea | 120 | } |
lukas_formanek | 15:bf11392ccaea | 121 | |
lukas_formanek | 15:bf11392ccaea | 122 | // write a register |
lukas_formanek | 15:bf11392ccaea | 123 | void DS3231::writeRegister(int reg,char byte) |
lukas_formanek | 15:bf11392ccaea | 124 | {char buf[2]; |
lukas_formanek | 15:bf11392ccaea | 125 | buf[0]=reg; |
lukas_formanek | 15:bf11392ccaea | 126 | buf[1]=byte; |
lukas_formanek | 15:bf11392ccaea | 127 | int w=i2c.write(DS3231_Address,buf,2); |
lukas_formanek | 15:bf11392ccaea | 128 | error=(w!=0); |
lukas_formanek | 15:bf11392ccaea | 129 | } |
lukas_formanek | 15:bf11392ccaea | 130 | |
lukas_formanek | 15:bf11392ccaea | 131 | void DS3231::eraseOSF() |
lukas_formanek | 15:bf11392ccaea | 132 | {int reg=readRegister(DS3231_Control_Status); |
lukas_formanek | 15:bf11392ccaea | 133 | reg=reg&0x7F; |
lukas_formanek | 15:bf11392ccaea | 134 | writeRegister(DS3231_Control_Status,reg); |
lukas_formanek | 15:bf11392ccaea | 135 | } |
lukas_formanek | 15:bf11392ccaea | 136 | |
lukas_formanek | 15:bf11392ccaea | 137 | bool DS3231::OSF() |
lukas_formanek | 15:bf11392ccaea | 138 | {int reg=readRegister(DS3231_Control_Status); |
lukas_formanek | 15:bf11392ccaea | 139 | return(reg&DS3231_bit_OSF); |
lukas_formanek | 16:610f7091e0ac | 140 | } |
lukas_formanek | 16:610f7091e0ac | 141 | |
lukas_formanek | 16:610f7091e0ac | 142 | uint16_t DS3231::set_cntl_stat_reg(ds3231_cntl_stat_t data) |
lukas_formanek | 16:610f7091e0ac | 143 | { |
lukas_formanek | 16:610f7091e0ac | 144 | uint8_t local_data[] = {0,0,0}; |
lukas_formanek | 16:610f7091e0ac | 145 | uint8_t data_length = 0; |
lukas_formanek | 16:610f7091e0ac | 146 | |
lukas_formanek | 16:610f7091e0ac | 147 | local_data[data_length++] = CONTROL; |
lukas_formanek | 16:610f7091e0ac | 148 | local_data[data_length++] = data.control; |
lukas_formanek | 16:610f7091e0ac | 149 | local_data[data_length++] = data.status; |
lukas_formanek | 16:610f7091e0ac | 150 | |
lukas_formanek | 16:610f7091e0ac | 151 | //users responsibility to make sure data is logical |
lukas_formanek | 16:610f7091e0ac | 152 | return(i2c.write(w_adrs,(const char*) local_data, data_length)); |
lukas_formanek | 16:610f7091e0ac | 153 | } |