He escrito la siguiente función para calcular la marca de tiempo actual (desde 00h 1 de enero de 1900). La salida que obtengo es:
Current Time & Date : 20:5:32 25/7/2014<\r>
2014 7 25 20 5 32<\r>
retval 1 3597523200<\r>
retval 2 3597523200<\r>
retval 3 3613161600<\r>
retval 4 3615235200<\r>
retval 5 3615241664<\r>
retval 6 3615241964<\r>
retval 7 3615241996<\r>
retval 8 3615241996<\r>
Current time timestamp 3615241996
Básicamente, estoy imprimiendo la retval (valor de retorno de la función) en cada paso para verificar y verificar los cálculos.
El cálculo coincide con hasta retval 4
(cuando las horas del día actual se convierten a segundos). Creo que podría deberse a un desbordamiento aritmético, pero no estoy seguro.
El problema parece estar ocurriendo en esta línea:
retval += (d.hr * 60 * 60); printf("retval 5 %"PRIu32"\r", retval);
retval es uint32_t y d.hr es uint16_t
uint32_t DS1307_GET_CURRENT_TIMESTAMP()
{
uint32_t retval = SECONDS_SINCE_1900_TO_2014;
ds1307 d;
DS1307_GET_DATETIME(&d);
printf("%u %u %u %u %u %u\r", d.yy,d.mm,d.dd,d.hr, d.min, d.sec);
printf("retval 1 %"PRIu32"\r", retval);
//process complete years since 2014 to current year
uint8_t i=0;
for(i=0; i<(d.yy - 2014); i++)
{
if(DS1307_IS_LEAP_YEAR(2014+i)==0) retval += 31622400;
else retval += 31536000;
}
printf("retval 2 %"PRIu32"\r", retval);
//process complete months from beginning of current year to current date/time
for(i=1; i<d.mm; i++)
{
if((i==1) || (i==3) || (i==5) || (i==7) || (i==8) || (i==10) || (i==12))
{
//31 days
retval += (31 * 86400);
}
else if ((i==4) || (i==6) || (i==9) || (i==11))
{
//30 days
retval += (30 * 86400);
}
else
{
//i==2==february. check if leap year
if(DS1307_IS_LEAP_YEAR(d.yy)==0) retval += (29 * 86400);
else retval += (28 * 86400);
}
}
printf("retval 3 %"PRIu32"\r", retval);
//process complete days from beginning of month till current date
retval += ((d.dd-1) * 86400);
printf("retval 4 %"PRIu32"\r", retval);
//process hours, min and seconds - CALCULATION DEVIATES HERE.
retval += (d.hr * 60 * 60); printf("retval 5 %"PRIu32"\r", retval);
retval += (d.min * 60); printf("retval 6 %"PRIu32"\r", retval);
retval += d.sec; printf("retval 7 %"PRIu32"\r", retval);
printf("retval 8 %"PRIu32"\r", retval);
return retval;
}