| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- // Copyright 2021 IOsetting <iosetting(at)outlook.com>
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "ds3231.h"
- __XDATA uint8_t buff[7];
- uint8_t DS3231_Write(uint8_t reg, uint8_t dat)
- {
- return I2C_Write(DS3231_I2C_ADDR, reg, &dat, 1);
- }
- uint8_t DS3231_Hex2Bcd(uint8_t hex)
- {
- return (hex % 10) + ((hex / 10) << 4);
- }
- uint8_t DS3231_Bcd2Hex(uint8_t bcd)
- {
- return (bcd >> 4) * 10 + (bcd & 0x0F);
- }
- uint8_t DS3231_GetStatus(void)
- {
- I2C_Read(DS3231_I2C_ADDR, DS3231_REG_STATUS, buff, 1);
- return buff[0];
- }
- uint8_t DS3231_GetTime(uint8_t *t)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_SECOND, buff, 7);
- if (res != HAL_OK)
- {
- return res;
- }
- t[0] = DS3231_Bcd2Hex(buff[6]) + ((buff[5] >> 7) & 0x01) * 100; // year
- t[1] = DS3231_Bcd2Hex(buff[5] & 0x1F); // month
- t[2] = DS3231_Bcd2Hex(buff[3]); // week
- t[3] = DS3231_Bcd2Hex(buff[4]); // date
- t[7] = (buff[2] >> 6) & 0x01; // 12h/24h
- t[8] = (buff[2] >> 5) & 0x01; // am/pm
- if (t[7] == DS3231_FORMAT_12H)
- {
- t[4] = DS3231_Bcd2Hex(buff[2] & 0x1F); // hour
- }
- else
- {
- t[4] = DS3231_Bcd2Hex(buff[2] & 0x3F); // hour
- }
- t[5] = DS3231_Bcd2Hex(buff[1]); // minute
- t[6] = DS3231_Bcd2Hex(buff[0]); // second
- return HAL_OK;
- }
- /**
- uint8_t year;
- uint8_t month;
- uint8_t week;
- uint8_t date;
- uint8_t hour;
- uint8_t minute;
- uint8_t second;
- DS3231_HourFormat_t format;
- DS3231_AmPm_t am_pm;
- */
- uint8_t DS3231_SetTime(uint8_t *t)
- {
- uint8_t res, reg;
- // Time validation
- if (t[0] > 200) t[0] = 200; // year
- if (t[1] == 0) t[1] = 1; // month
- else if (t[1] > 12) t[1] = 12;
- if (t[2] == 0) t[2] = 1; // week
- else if (t[2] > 7) t[2] = 7;
- if (t[3] == 0) t[3] = 1; // date
- else if (t[3] > 31) t[3] = 31;
- if (t[7] == DS3231_FORMAT_12H)
- {
- if (t[4] > 12) t[4] = 12; // hour
- }
- else if (t[7] == DS3231_FORMAT_24H)
- {
- if (t[4] > 23) t[4] = 23; // hour
- }
- if (t[5] > 59) t[5] = 59; // minute
- if (t[6] > 59) t[6] = 59; // second
- res = DS3231_Write(DS3231_REG_SECOND, DS3231_Hex2Bcd(t[6]));
- if (res != HAL_OK) return res;
- res = DS3231_Write(DS3231_REG_MINUTE, DS3231_Hex2Bcd(t[5]));
- if (res != HAL_OK) return res;
- if (t[7] == DS3231_FORMAT_12H)
- {
- reg = (uint8_t)((1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));
- }
- else
- {
- reg = (0 << 6) | DS3231_Hex2Bcd(t[4]);
- }
- res = DS3231_Write(DS3231_REG_HOUR, reg);
- if (res != HAL_OK) return res;
- res = DS3231_Write(DS3231_REG_WEEK, DS3231_Hex2Bcd(t[2]));
- if (res != HAL_OK) return res;
- res = DS3231_Write(DS3231_REG_DATE, DS3231_Hex2Bcd(t[3]));
- if (res != HAL_OK) return res;
- if (t[0] >= 100)
- {
- res = DS3231_Write(DS3231_REG_MONTH, DS3231_Hex2Bcd(t[1]) | (1 << 7));
- if (res != HAL_OK) return res;
- return DS3231_Write(DS3231_REG_YEAR, DS3231_Hex2Bcd(t[0] - 100));
- }
- else
- {
- res = DS3231_Write(DS3231_REG_MONTH, DS3231_Hex2Bcd(t[1]));
- if (res != HAL_OK) return res;
- return DS3231_Write(DS3231_REG_YEAR, DS3231_Hex2Bcd(t[0]));
- }
- }
- uint8_t DS3231_GetPin(DS3231_PinType_t *pin)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
- if (res != HAL_OK) return res;
- *pin = (DS3231_PinType_t)((buff[0] >> 2) & 0x01);
- return HAL_OK;
- }
- uint8_t DS3231_SetPin(DS3231_PinType_t *pin)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
- if (res != HAL_OK) return res;
- buff[0] &= ~(1 << 2);
- buff[0] |= (*pin) << 2;
- return DS3231_Write(DS3231_REG_CONTROL, buff[0]);
- }
- uint8_t ds3231_GetSquareOutputState(HAL_State_t *state)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
- if (res != HAL_OK) return res;
- *state = (HAL_State_t)((buff[0] >> 6) & 0x01);
- return HAL_OK;
- }
- uint8_t DS3231_SetSquareOutputState(HAL_State_t state)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
- if (res != HAL_OK) return res;
- buff[0] &= ~(1 << 6);
- buff[0] |= state << 6;
- return DS3231_Write(DS3231_REG_CONTROL, buff[0]);
- }
- uint8_t DS3231_GetAlarmInterrupt(DS3231_Alarm_t alarm, HAL_State_t *state)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
- if (res != HAL_OK) return res;
- *state = (HAL_State_t)((buff[0] >> alarm) & 0x01);
- return HAL_OK;
- }
- uint8_t DS3231_SetAlarmInterrupt(DS3231_Alarm_t alarm, HAL_State_t state)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_CONTROL, buff, 1);
- if (res != HAL_OK) return res;
- buff[0] &= ~(1 << alarm);
- buff[0] |= state << alarm;
- return DS3231_Write(DS3231_REG_CONTROL, buff[0]);
- }
- uint8_t DS3231_GetAlarm1(uint8_t *t, DS3231_Alarm1Mode_t *mode)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_ALARM1_SECOND, buff, 4);
- if (res != HAL_OK) return res;
- t[0] = 0; // year
- t[1] = 0; // month
- if (((buff[3] >> 6) & 0x01) != 0) // if week
- {
- t[2] = DS3231_Bcd2Hex(buff[3] & 0x0F); // week
- t[3] = 0; // date
- }
- else // if date
- {
- t[2] = 0; // week
- t[3] = DS3231_Bcd2Hex(buff[3] & 0x3F); // date
- }
- t[8] = ((buff[2] >> 5) & 0x01); // am/pm
- t[7] = ((buff[2] >> 6) & 0x01); // 12h/24h
- if (t[7] == DS3231_FORMAT_12H)
- {
- t[4] = DS3231_Bcd2Hex(buff[2]&0x1F);
- }
- else
- {
- t[4] = DS3231_Bcd2Hex(buff[2]&0x3F);
- }
- t[5] = DS3231_Bcd2Hex(buff[1] & 0x7F);
- t[6] = DS3231_Bcd2Hex(buff[0] & 0x7F);
- *mode = (DS3231_Alarm1Mode_t)(
- ((buff[0]>>7)&0x01)<<0 |
- ((buff[1]>>7)&0x01)<<1 |
- ((buff[2]>>7)&0x01)<<2 |
- ((buff[3]>>7)&0x01)<<3 |
- ((buff[3]>>6)&0x01)<<4
- );
- return HAL_OK;
- }
- uint8_t DS3231_SetAlarm1(uint8_t *t, DS3231_Alarm1Mode_t mode)
- {
- uint8_t res;
- uint8_t reg;
- res = DS3231_Write(DS3231_REG_ALARM1_SECOND, DS3231_Hex2Bcd(t[6]) | ((mode & 0x01) << 7));
- if (res != HAL_OK) return res;
- res = DS3231_Write(DS3231_REG_ALARM1_MINUTE, DS3231_Hex2Bcd(t[5]) | (((mode >> 1) & 0x01) << 7));
- if (res != HAL_OK) return res;
- if (t[7] == DS3231_FORMAT_12H)
- {
- reg = (uint8_t)((((mode >> 2) & 0x01) << 7) | (1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));
- }
- else
- {
- reg = (((mode >> 2) & 0x01) << 7) | DS3231_Hex2Bcd(t[4]);
- }
- res = DS3231_Write(DS3231_REG_ALARM1_HOUR, reg);
- if (res != HAL_OK) return res;
- if (mode >= DS3231_ALARM1_MODE_WEEK_HOUR_MINUTE_SECOND_MATCH)
- {
- reg = (((mode >> 3) & 0x01) << 7) | (1 << 6) | DS3231_Hex2Bcd(t[2]);
- }
- else
- {
- reg = (((mode >> 3) & 0x01) << 7) | DS3231_Hex2Bcd(t[3]);
- }
- return DS3231_Write(DS3231_REG_ALARM1_WEEK, reg);
- }
- uint8_t DS3231_GetAlarm2(uint8_t *t, DS3231_Alarm2Mode_t *mode)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_ALARM2_MINUTE, buff, 3);
- if (res != HAL_OK) return res;
- t[0] = 0; // year
- t[1] = 0; // month
- if (((buff[2] >> 6) & 0x01) != 0) // if week
- {
- t[2] = DS3231_Bcd2Hex(buff[2] & 0x0F);
- t[3] = 0;
- }
- else // if date
- {
- t[2] = 0;
- t[3] = DS3231_Bcd2Hex(buff[2] & 0x3F);
- }
- t[8] = ((buff[1] >> 5) & 0x01); // am/pm
- t[7] = ((buff[1] >> 6) & 0x01); // 12h/24h
- if (t[7] == DS3231_FORMAT_12H)
- {
- t[4] = DS3231_Bcd2Hex(buff[1]&0x1F);
- }
- else
- {
- t[4] = DS3231_Bcd2Hex(buff[1]&0x3F);
- }
- t[5] = DS3231_Bcd2Hex(buff[0] & 0x7F);
- t[6] = 0;
- *mode = (DS3231_Alarm2Mode_t)(
- ((buff[0]>>7)&0x01)<<0 |
- ((buff[1]>>7)&0x01)<<1 |
- ((buff[2]>>7)&0x01)<<2 |
- ((buff[2]>>6)&0x01)<<4
- );
- return HAL_OK;
- }
- uint8_t DS3231_SetAlarm2(uint8_t *t, DS3231_Alarm2Mode_t mode)
- {
- uint8_t res;
- uint8_t reg;
- res = DS3231_Write(DS3231_REG_ALARM2_MINUTE, DS3231_Hex2Bcd(t[5]) | (((mode >> 0) & 0x01) << 7));
- if (res != HAL_OK) return res;
- if (t[7] == DS3231_FORMAT_12H)
- {
- reg = (uint8_t)((((mode >> 1) & 0x01) << 7) | (1 << 6) | (t[8] << 5) | DS3231_Hex2Bcd(t[4]));
- }
- else
- {
- reg = (((mode >> 1) & 0x01) << 7) | DS3231_Hex2Bcd(t[4]);
- }
- res = DS3231_Write(DS3231_REG_ALARM2_HOUR, reg);
- if (res != HAL_OK) return res;
- if (mode >= DS3231_ALARM2_MODE_WEEK_HOUR_MINUTE_MATCH)
- {
- reg = (((mode >> 2) & 0x01) << 7) | (1 << 6) | DS3231_Hex2Bcd(t[2]);
- }
- else
- {
- reg = (((mode >> 2) & 0x01) << 7) | DS3231_Hex2Bcd(t[3]);
- }
- return DS3231_Write(DS3231_REG_ALARM2_WEEK, reg);
- }
- uint8_t DS3231_ClearAlarm(DS3231_Alarm_t alarm)
- {
- uint8_t res;
- res = I2C_Read(DS3231_I2C_ADDR, DS3231_REG_STATUS, buff, 1);
- if (res != HAL_OK) return res;
- buff[0] &= ~(1 << alarm);
- return DS3231_Write(DS3231_REG_STATUS, buff[0]);
- }
|