##// END OF EJS Templates
update de firmware timegine. RTC terminado
update de firmware timegine. RTC terminado

File last commit:

r196:197
r196:197
Show More
rtc1308.cpp
163 lines | 4.1 KiB | text/x-c | CppLexer
/*
* rtc1308.cpp
*
* Created on: Nov 4, 2014
* Author: Alan Aguilar Sologuren
*/
#include <rtc1308.h>
#include <Wire.h>
/*!
* \fn initialization
* \brief Inicializacion del modulo que controlara al RTC DS1308.
*/
bool te_rtc_initialization(void) {
pinMode(CLKIN,OUTPUT);
attachInterrupt(PPS,ISR_gnss_pps, RISING);
}
/*!
* \fn configure
* \brief Configura el IC DS1308 para operacion con un PPS de GNSS como tick.
* \param rtc estructura que contien informacion de configuracion.
* \see rtc_config_struct
*/
bool te_rtc_configure(rtc_config_struct &rtc) {
uint8_t *ctl_byte = (uint8_t*)&rtc.ctl_byte;
uint8_t *clk_halt = (uint8_t*)&rtc.clk_halt;
Wire.beginTransmission(DS1308_CTRL_ID);
Wire.write(DS1308_CTL_ADD);
Wire.write(*clk_halt);
Wire.endTransmission();
Wire.beginTransmission(DS1308_CTRL_ID);
Wire.write(DS1308_CTL_ADD);
// CLKIN com 1Hz de entrada (1PPS)
Wire.write(*ctl_byte);
//Wire.write(1<<ECLK|0<<OSF|0<<LOS|0<<BBCLK|0<<RS1|0<<RS0);
Wire.endTransmission();
return true;
}
/*!
* \fn activate_pps
* \brief Activa la generacion de una senal de 1Hz (PPS) desde el RTC DS1308. Este
* PPS debe estar sincronizado con el PPS del GNSS.
*/
bool te_rtc_activate_pps(bool actv) {
uint8_t value;
value = actv?(1<<ECLK):0x00;
return te_rtc_write_reg(DS1308_CTL_ADD,&value,1)==0;
}
/*!
* \fn set_time
* \brief Setea el tiempo especificado en tm, en el IC DS1308.
* \param tm estructura que contien informacion de tiempo.
* \see tmElements_t
*/
bool te_rtc_set_date_time(gnss_precise_time &gt) {
uint8_t ptrvalues[7];
ptrvalues[0] = dec2bcd(gt.sec);
ptrvalues[1] = dec2bcd(gt.minu);
ptrvalues[2] = dec2bcd(gt.hour);
ptrvalues[3] = dec2bcd(0);
ptrvalues[4] = dec2bcd(gt.day);
ptrvalues[5] = dec2bcd(gt.month);
ptrvalues[6] = dec2bcd(tmYearToY2k(gt.year-2000));
return te_rtc_write_reg(DS1308_SEC_ADD, ptrvalues, 7)==0;
}
bool te_rtc_read_date_time(gnss_precise_time &gt){
uint8_t ptrvalues[7];
bool ret =te_rtc_read_reg(DS1308_SEC_ADD, ptrvalues, 7)==7;
gt.sec = bcd2dec(ptrvalues[0]);
gt.minu = bcd2dec(ptrvalues[1]);
gt.hour = bcd2dec(ptrvalues[2]);
gt.day = bcd2dec(ptrvalues[4]);
gt.month = bcd2dec(ptrvalues[5]);
gt.year = bcd2dec(y2kYearToTm(ptrvalues[6]))+2000;
return ret;
}
///////////////////////////////////////////////////////////////////////////////
/*!
* \fn read_ram
* \brief Lee un buffer de la memoria RAM interna del RTC DS1308, de la
* direccion especificada.
* \param addr direccion relativa a la RAM (0 es la primera) del registro
* en DS1308.
* \param buff Direccion del buffer al cual se copiaran los valores.
* \param cnt Numero de elementos acpiar del DS1308.
* \return estatus
* 0 success
* 2 error: address send, nack received
* 3 error: data send, nack received
* 4 other twi error
*/
uint8_t te_rtc_read_reg(uint8_t regaddr, uint8_t *pbuf, uint8_t cnt) {
uint8_t nread=0;
while(cnt > 0 ) {
Wire.beginTransmission(DS1308_CTRL_ID);
Wire.write(regaddr);
Wire.endTransmission();
Wire.requestFrom((uint8_t)DS1308_CTRL_ID, cnt);
while(Wire.available() && (cnt > 0) ) {
pbuf[nread] = Wire.read();
nread++; cnt--; regaddr++;
} /* while */
}
return (nread);
}
/*!
* \fn write_ram
* \brief Escribe el contenido de un buffer de cnt elementos en la memoria
* RAM interna del RTC DS1308, en la direccion especificada.
* \param addr direccion relativa a la RAM (0 es la primera) del inicio del
* buffer en DS1308.
* \param pbuf direccion del buffer a copiar en la RAM del DS1308.
* \param cnt Numero de elementos a copiar.
* \return estatus
* 0 success
* 2 error: address send, nack received
* 3 error: data send, nack received
* 4 other twi error
*/
uint8_t te_rtc_write_reg(uint8_t regaddr,uint8_t *pbuf,uint8_t cnt) {
uint8_t nbytes, rc=0;
while (cnt > 0) {
nbytes = cnt;
Wire.beginTransmission(DS1308_CTRL_ID);
Wire.write(regaddr);
Wire.write((uint8_t*)pbuf, nbytes);
rc = Wire.endTransmission();
cnt -=nbytes;
regaddr+=nbytes;
pbuf +=nbytes;
}
return rc;
}
// Convert Decimal to Binary Coded Decimal (BCD). 2 digits only
inline uint8_t dec2bcd(uint8_t val) {
return val + 6 * (val / 10);
}
inline uint8_t bcd2dec(uint8_t val){
return (val>>4)*10 + (val&0x0f);
}