File content as of revision 2:3710775b1864:
/**
* @brief DS3231.cpp
* @details Extremely Accurate I2C-Integrated RTC/TCXO/Crystal.
* Function file.
*
*
* @return NA
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN.
* @warning NaN
* @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
*/
#include "DS3231.h"
DS3231::DS3231 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq )
: _i2c ( sda, scl )
, _DS3231_Addr ( addr )
{
_i2c.frequency( freq );
}
DS3231::~DS3231()
{
}
/**
* @brief DS3231_ReadTemperature ( DS3231_vector_data_t* )
*
* @details It gets the temperature.
*
* @param[in] NaN
*
* @param[out] myTemperature: Temperature data.
*
*
* @return Status of DS3231_ReadTemperature.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre The temperature registers are updated after each user-initiated conversion and on every 64-second conversion.
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_ReadTemperature ( DS3231_vector_data_t* myTemperature )
{
char cmd[] = { DS3231_MSB_TEMPERATURE, 0 };
uint32_t aux = 0;
// It gets the temperature
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );
// Parse the data
// 1. Check if the Temperature is positive or negative
if ( ( cmd[0] & 0b10000000 ) == 0b00000000 )
myTemperature->Temperature = cmd[0]; // Positive value
else
myTemperature->Temperature = -1.0 * ( ( ~cmd[0] ) + 1 ); // Negative value
// 2. Decimal part. 0.25°C resolution
switch( cmd[1] )
{
// x.00°C
default:
case 0b00000000:
break;
// x.25°C
case 0b01000000:
myTemperature->Temperature += 0.25;
break;
// x.50°C
case 0b10000000:
myTemperature->Temperature += 0.50;
break;
// x.75°C
case 0b11000000:
myTemperature->Temperature += 0.75;
break;
}
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_ReadRawTemperature ( DS3231_vector_data_t* )
*
* @details It gets the raw temperature.
*
* @param[in] NaN
*
* @param[out] myRawTemperature: Raw Temperature data.
*
*
* @return Status of DS3231_ReadTemperature.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre The temperature registers are updated after each user-initiated conversion and on every 64-second conversion.
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_ReadRawTemperature ( DS3231_vector_data_t* myRawTemperature )
{
char cmd[] = { DS3231_MSB_TEMPERATURE, 0 };
uint32_t aux = 0;
// It gets the temperature
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );
// Parse the data
myRawTemperature->MSBTemperature = cmd[0];
myRawTemperature->LSBTemperature = cmd[1];
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_StartNewConvertTemperature ( void )
*
* @details It triggers a new temperature conversion.
*
* @param[in] NaN.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_StartNewConvertTemperature.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_StartNewConvertTemperature ( void )
{
char cmd[] = { DS3231_CONTROL_STATUS, 0 };
uint32_t aux = 0;
uint32_t ii = 0;
// BSY MUST be checked before triggering a new temperature conversion
do
{
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
ii++;
}
while ( ( ( cmd[1] & STATUS_BUSY_MASK ) != STATUS_BUSY_NOBUSY ) && ( ii < DS3231_TIMEOUT ) );
// if something went wrong, there will not be a new temperature conversion
cmd[0] = DS3231_CONTROL;
if ( ii < DS3231_TIMEOUT )
{
// It triggers a new temperature conversion
// It reads CONTROL register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
// Start a new temperature conversion
cmd[1] |= CONTROL_STATUS_CONVERT_TEMPERATURE_ENABLED;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Wait until the temperature conversion is completed
ii = 0;
do
{
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
ii++;
}
while ( ( ( cmd[1] & CONTROL_STATUS_CONVERT_TEMPERATURE_MASK ) != CONTROL_STATUS_CONVERT_TEMPERATURE_DISABLED ) && ( ii < DS3231_TIMEOUT ) );
}
// If TIMEOUT happens, something went wrong!
if ( ii >= DS3231_TIMEOUT )
aux = I2C_FAILURE;
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_ReadRawAging ( DS3231_vector_data_t* )
*
* @details It gets the raw aging.
*
* @param[in] NaN
*
* @param[out] myRawAging: Raw Aging data.
*
*
* @return Status of DS3231_ReadRawAging.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_ReadRawAging ( DS3231_vector_data_t* myRawAging )
{
char cmd = DS3231_AGING_OFFSET;
uint32_t aux = 0;
// It gets the raw aging value
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myRawAging->RawAging = cmd;
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_Status32kHzPin ( DS3231_status_enable_32khz_output_t )
*
* @details It enables/disables the 32kHz output pin.
*
* @param[in] my32kHzPin: 32kHz pin enabled/disabled.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_Status32kHzPin.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_Status32kHzPin ( DS3231_status_enable_32khz_output_t my32kHzPin )
{
char cmd[] = { DS3231_CONTROL_STATUS, 0 };
uint32_t aux = 0;
// It reads the status register to parse the data
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
cmd[1] &= ~STATUS_ENABLE_32KHZ_OUTPUT_MASK;
cmd[1] |= my32kHzPin;
// Update the register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_ClearAlarmFlag ( DS3231_status_alarm1_flag_t , DS3231_status_alarm2_flag_t )
*
* @details It clears alarm flags.
*
* @param[in] myA1F: Reset/Mask alarm 1 flag.
* @param[in] myA2F: Reset/Mask alarm 2 flag.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_ClearAlarmFlag.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_ClearAlarmFlag ( DS3231_status_alarm1_flag_t myA1F, DS3231_status_alarm2_flag_t myA2F )
{
char cmd[] = { DS3231_CONTROL_STATUS, 0 };
uint32_t aux = 0;
// It reads the status register to parse the data
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
cmd[1] &= ~( STATUS_ALARM1_FLAG_MASK | STATUS_ALARM2_FLAG_MASK );
cmd[1] |= ( myA1F | myA2F );
// Update the register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_SetAlarm1 ( DS3231_alarm1_register_t )
*
* @details It sets the alarm 1.
*
* @param[in] myAlarm1: Alarm 1 options.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_SetAlarm1.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_SetAlarm1 ( DS3231_alarm1_register_t myAlarm1 )
{
char cmd[] = { 0, 0 };
uint32_t aux = 0;
uint32_t Alarm1SecondAux = 0; // A1M1
uint32_t Alarm1MinuteAux = 0; // A1M2
uint32_t Alarm1HourAux = 0; // A1M3
uint32_t Alarm1DayDateAux = 0; // A1M4 & DYDT
// Read all the registers involved in the alarm1
// A1M1
cmd[0] = DS3231_ALARM_1_SECONDS;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm1SecondAux = ( cmd[1] & ~ALARM1_A1M1_MASK );
// A1M2
cmd[0] = DS3231_ALARM_1_MINUTES;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm1MinuteAux = ( cmd[1] & ~ALARM1_A1M2_MASK );
// A1M3
cmd[0] = DS3231_ALARM_1_HOURS;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm1HourAux = ( cmd[1] & ~ALARM1_A1M3_MASK );
// A1M4 & DY/#DT
cmd[0] = DS3231_ALARM_1_DAY_DATE;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm1DayDateAux = ( cmd[1] & ~( ALARM1_A1M4_MASK | ALARM1_DYDT_MASK ) );
// Set all ( A1M1, A1M2, A1M3 A1M4 and DY/#DT ) to 0
cmd[0] = DS3231_ALARM_1_SECONDS;
cmd[1] = Alarm1SecondAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
cmd[0] = DS3231_ALARM_1_MINUTES;
cmd[1] = Alarm1MinuteAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
cmd[0] = DS3231_ALARM_1_HOURS;
cmd[1] = Alarm1HourAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
cmd[0] = DS3231_ALARM_1_DAY_DATE;
cmd[1] = Alarm1DayDateAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update the Alarm 1 rate
switch ( myAlarm1 )
{
case ALARM1_ALARM_ONCE_PER_SECOND:
cmd[0] = DS3231_ALARM_1_SECONDS;
cmd[1] = ( Alarm1SecondAux | ALARM1_A1M1_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
case ALARM1_WHEN_SECONDS_MATCH:
cmd[0] = DS3231_ALARM_1_MINUTES;
cmd[1] = ( Alarm1MinuteAux | ALARM1_A1M2_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
case ALARM1_WHEN_MINUTES_AND_SECONDS_MATCH:
cmd[0] = DS3231_ALARM_1_HOURS;
cmd[1] = ( Alarm1HourAux | ALARM1_A1M3_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
case ALARM1_WHEN_HOURS_MINUTES_AND_SECONDS_MATCH:
cmd[0] = DS3231_ALARM_1_DAY_DATE;
cmd[1] = ( Alarm1DayDateAux | ALARM1_A1M4_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
break;
default:
case ALARM1_WHEN_DATE_HOURS_MINUTES_AND_SECONDS_MATCH:
break;
case ALARM1_WHEN_DAY_HOURS_MINUTES_AND_SECONDS_MATCH:
cmd[0] = DS3231_ALARM_1_DAY_DATE;
cmd[1] = ( Alarm1DayDateAux | ALARM1_DYDT_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
break;
}
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_SetAlarm2 ( DS3231_alarm2_register_t )
*
* @details It sets the alarm 2.
*
* @param[in] myAlarm1: Alarm 2 options.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_SetAlarm2.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_SetAlarm2 ( DS3231_alarm2_register_t myAlarm2 )
{
char cmd[] = { 0, 0 };
uint32_t aux = 0;
uint32_t Alarm2MinuteAux = 0; // A2M2
uint32_t Alarm2HourAux = 0; // A2M3
uint32_t Alarm2DayDateAux = 0; // A2M3 & DYDT
// Read all the registers involved in the alarm2
// A2M2
cmd[0] = DS3231_ALARM_2_MINUTES;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm2MinuteAux = ( cmd[1] & ~ALARM2_A2M2_MASK );
// A2M3
cmd[0] = DS3231_ALARM_2_HOURS;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm2HourAux = ( cmd[1] & ~ALARM2_A2M3_MASK );
// A2M4 & DY/#DT
cmd[0] = DS3231_ALARM_2_DAY_DATE;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
Alarm2DayDateAux = ( cmd[1] & ~( ALARM2_A2M4_MASK | ALARM2_DYDT_MASK ) );
// Set all ( A2M2, A2M3 A2M4 and DY/#DT ) to 0
cmd[0] = DS3231_ALARM_2_MINUTES;
cmd[1] = Alarm2MinuteAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
cmd[0] = DS3231_ALARM_2_HOURS;
cmd[1] = Alarm2HourAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
cmd[0] = DS3231_ALARM_2_DAY_DATE;
cmd[1] = Alarm2DayDateAux;
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update the Alarm 2 rate
switch ( myAlarm2 )
{
case ALARM2_ALARM_ONCE_PER_MINUTE:
cmd[0] = DS3231_ALARM_2_MINUTES;
cmd[1] = ( Alarm2MinuteAux | ALARM2_A2M2_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
case ALARM2_WHEN_MINUTES_MATCH:
cmd[0] = DS3231_ALARM_2_HOURS;
cmd[1] = ( Alarm2HourAux | ALARM2_A2M3_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
case ALARM2_WHEN_HOURS_MINUTES_MATCH:
cmd[0] = DS3231_ALARM_2_DAY_DATE;
cmd[1] = ( Alarm2DayDateAux | ALARM2_A2M4_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
break;
default:
case ALARM2_WHEN_DATE_HOURS_AND_MINUTES_MATCH:
break;
case ALARM2_WHEN_DAY_HOURS_AND_MINUTES_MATCH:
cmd[0] = DS3231_ALARM_2_DAY_DATE;
cmd[1] = ( Alarm2DayDateAux | ALARM2_DYDT_MASK );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
break;
}
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_SetAlarmsInterrupt ( DS3231_control_status_alarm1_t , DS3231_control_status_alarm2_t )
*
* @details It enables/disable alarm interrupts.
*
* @param[in] myAlarm1: Enable/Disable Alarm1 interrupt.
* @param[in] myAlarm2: Enable/Disable Alarm2 interrupt.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_SetAlarmsInterrupt.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_SetAlarmsInterrupt ( DS3231_control_status_alarm1_t myAlarm1, DS3231_control_status_alarm2_t myAlarm2 )
{
char cmd[] = { DS3231_CONTROL, 0 };
uint32_t aux = 0;
// Read the Control Register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
// Parse the data
cmd[1] &= ~( CONTROL_STATUS_ALARM1_MASK | CONTROL_STATUS_ALARM2_MASK );
cmd[1] |= ( myAlarm1 | myAlarm2 );
// If both alarms are off then, disables the alarm interrupts, enables them otherwise.
if ( ( myAlarm1 == CONTROL_STATUS_ALARM1_DISABLED ) && ( myAlarm2 == CONTROL_STATUS_ALARM2_DISABLED ) )
cmd[1] &= ~CONTROL_STATUS_INTERRUPT_CONTROL_MASK;
else
cmd[1] |= CONTROL_STATUS_INTERRUPT_CONTROL_INT;
// Update the register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_SetSquareWaveOutput ( DS3231_control_status_rate_select_t )
*
* @details It enables/disable the square-wave output.
*
* @param[in] myRate: Square-wave output frequency.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_SetSquareWaveOutput.
*
*
* @author Manuel Caballero
* @date 19/December/2017
* @version 19/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_SetSquareWaveOutput ( DS3231_control_status_rate_select_t myRate )
{
char cmd[] = { DS3231_CONTROL, 0 };
uint32_t aux = 0;
// Read the Control Register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd[1], 1 );
// Parse the data
cmd[1] &= ~CONTROL_STATUS_RATE_SELECT_MASK;
cmd[1] |= myRate;
// Enable the square-wave output.
cmd[1] &= ~CONTROL_STATUS_INTERRUPT_CONTROL_MASK;
// Update the register
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_GetDate ( DS3231_vector_date_time_t* )
*
* @details It gets the date.
*
* @param[in] myDate: Current Date.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_GetDate.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_GetDate ( DS3231_vector_date_time_t* myDate )
{
char cmd = 0;
uint32_t aux = 0;
// Read Date Register
cmd = DS3231_DATE;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myDate->Date = _MYBCD_TO_DECIMAL( cmd );
// Read Month Register
cmd = DS3231_MONTH_CENTURY;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myDate->Month = _MYBCD_TO_DECIMAL( cmd & MONTH_MONTH_MASK );
myDate->Century = _MYBCD_TO_DECIMAL( cmd & MONTH_CENTURY_MASK );
// Read Year Register
cmd = DS3231_YEAR;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myDate->Year = _MYBCD_TO_DECIMAL( cmd );
// Read Day of the Week Register
cmd = DS3231_DAY;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myDate->DayOfWeek = _MYBCD_TO_DECIMAL( cmd );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_SetDate ( DS3231_vector_date_time_t )
*
* @details It sets the date.
*
* @param[in] myTime: Date to store.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_SetDate.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_SetDate ( DS3231_vector_date_time_t myDate )
{
char cmd[] = { 0, 0 };
uint32_t aux = 0;
// Update Date Register
cmd[0] = DS3231_DATE;
cmd[1] = _MYDECIMAL_TO_BCD( myDate.Date );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update Month Register
cmd[0] = DS3231_MONTH_CENTURY;
cmd[1] = _MYDECIMAL_TO_BCD( myDate.Month | myDate.Century );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update Year Register
cmd[0] = DS3231_YEAR;
cmd[1] = _MYDECIMAL_TO_BCD( myDate.Year );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update Day Register
cmd[0] = DS3231_DAY;
cmd[1] = _MYDECIMAL_TO_BCD( myDate.DayOfWeek );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_GetTime ( DS3231_vector_date_time_t* )
*
* @details It gets the time in decimal.
*
* @param[in] myTime: Current Time.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_GetTime.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_GetTime ( DS3231_vector_date_time_t* myTime )
{
char cmd = 0;
uint32_t aux = 0;
// Read Hours Register
cmd = DS3231_HOURS;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myTime->Hours = _MYBCD_TO_DECIMAL( ( cmd & ~( HOURS_nAM_PM_MASK | HOURS_12_n24_MASK ) ) );
myTime->Mode_nAM_PM = ( cmd & HOURS_nAM_PM_MASK );
myTime->Mode_12_n24 = ( cmd & HOURS_12_n24_MASK );
// Read Minutes Register
cmd = DS3231_MINUTES;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myTime->Minutes = _MYBCD_TO_DECIMAL( cmd );
// Read Seconds Register
cmd = DS3231_SECONDS;
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myTime->Seconds = _MYBCD_TO_DECIMAL( cmd );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_SetTime ( DS3231_vector_date_time_t )
*
* @details It sets the time in BCD.
*
* @param[in] myTime: Time to store.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_SetTime.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_SetTime ( DS3231_vector_date_time_t myTime )
{
char cmd[] = { 0, 0 };
uint32_t aux = 0;
// Update Hours Register
cmd[0] = DS3231_HOURS;
cmd[1] = ( _MYDECIMAL_TO_BCD( myTime.Hours ) | myTime.Mode_12_n24 | myTime.Mode_nAM_PM );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update Minutes Register
cmd[0] = DS3231_MINUTES;
cmd[1] = _MYDECIMAL_TO_BCD( myTime.Minutes );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
// Update Seconds Register
cmd[0] = DS3231_SECONDS;
cmd[1] = _MYDECIMAL_TO_BCD( myTime.Seconds );
aux = _i2c.write ( _DS3231_Addr, &cmd[0], 2, false );
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}
/**
* @brief DS3231_GetControlStatusRegister ( DS3231_vector_data_t* )
*
* @details It gets the Control/Status register.
*
* @param[in] myControlStatusReg: Current value of the Register.
*
* @param[out] NaN.
*
*
* @return Status of DS3231_GetControlStatusRegister.
*
*
* @author Manuel Caballero
* @date 20/December/2017
* @version 20/December/2017 The ORIGIN
* @pre NaN
* @warning NaN.
*/
DS3231::DS3231_status_t DS3231::DS3231_GetControlStatusRegister ( DS3231_vector_data_t* myControlStatusReg )
{
char cmd = DS3231_CONTROL_STATUS;
uint32_t aux = 0;
// Read Control/Status Register
aux = _i2c.write ( _DS3231_Addr, &cmd, 1, true );
aux = _i2c.read ( _DS3231_Addr, &cmd, 1 );
myControlStatusReg->Control_Status_Register = cmd;
if ( aux == I2C_SUCCESS )
return DS3231_SUCCESS;
else
return DS3231_FAILURE;
}