DS3231 RTClib.h library

Ds3231SqwPinMode RTC_DS3231::readSqwPinMode() {
int mode;

Wire.beginTransmission(DS3231_ADDRESS);
Wire._I2C_WRITE(DS3231_CONTROL);
Wire.endTransmission();

Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1);
mode = Wire._I2C_READ();

mode &= 0x1C;
if (mode & 0x04)
mode = DS3231_OFF;
return static_cast(mode);

I need help to the statement , how does it works? :
mode &= 0x1C;
if (mode & 0x04)
mode = DS3231_OFF

mode &= 0x1C; performs a bitwise AND between the value of mode and 1C hex, (binary 00011100) and puts the result back in the mode variable

mode & 0x04 performs a bitwise AND between the new value of mode and 04 hex (binary 00000100) and if the result is true (ie bit 2 is set so the result is not zero) then mode is set to the value of the DS3131_OFF constant

Why the code would do that I don't know

Hi UKHeliBob,
ok now I get it.
Last request about RTC library is about the statement :

bool DS3232RTC::oscStopped(bool clearOSF)
{
uint8_t s = readRTC(RTC_STATUS); // read the status register --> That's OK
bool ret = s & _BV(OSF); // isolate the osc stop flag to return to caller how does it works?
if (ret && clearOSF) // clear OSF if it's set and the caller wants to clear it
{
writeRTC( RTC_STATUS, s & ~_BV(OSF) );

}
return ret;

datasheet

_BV is a macro which returns the “value” of a bit . It is: defined like this
_BV(bit) (1 << (bit))
So, for example, _BV(2) expands to (1<<(2)), which is 0b00000001 shifted left twice: 0b00000100

_BV(OSF) equates to _BV(0x0F), ie 0b1000000000000000

The rest is just bitwise AND and a logical AND

Hi UKHeliBob,
thanks for your reply.
One thing is not clear to me.
I see that BV(OSF) equates to _BV(0x0F), ie 0b1000000000000000. Why you consider the register address?...In my mind I thought I had to consider OSF bit --> BV(OSF) = 0b10000000

Bearing in mind that it is not actually me considering anything, 0b10000000 if 0x80 but OSF is 0x0F

Personally I have never found the _BV() macro useful and think that you might just as well use explicit bit shifting to make it more obvious what is going on

In my mind I thought I had to consider OSF bit --> BV(OSF) = 0b10000000

Correct.

bool DS3232RTC::oscStopped(bool clearOSF)
{
    uint8_t s = readRTC(RTC_STATUS);    // read the status register
    bool ret = s & _BV(OSF);            // isolate the osc stop flag to return to caller
    if (ret && clearOSF)                // clear OSF if it's set and the caller wants to clear it
    {
        writeRTC( RTC_STATUS, s & ~_BV(OSF) );
    }
    return ret;
}

This code appears to be from https://github.com/JChristensen/DS3232RTC

As you show in the register map, OSF is the name of a bit7 in the control/status register(0x0F).

What you have not seen is that in the .cpp file of the library there is this definition list

// Status register bits
#define OSF 7
#define BB32KHZ 6
#define CRATE1 5
#define CRATE0 4
#define EN32KHZ 3
#define BSY 2
#define A2F 1
#define A1F 0

Therefore you get
_BV(OSF) equal to (1 << 7) equal to 0b10000000

cattledog....now I see the light :slight_smile:
thanks a lot