##// END OF EJS Templates
Versión inicial de los bloques de comunicación para el módulo de procesamiento.
Versión inicial de los bloques de comunicación para el módulo de procesamiento.

File last commit:

r209:210
r219:220
Show More
rtc1308.cpp
160 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>
namespace te_rtc{
/*!
* \fn initialization
* \brief Inicializacion del modulo que controlara al RTC DS1308.
*/
bool 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 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 activate_pps(bool actv) {
uint8_t value;
value = actv ? (1 << ECLK) : 0x00;
return 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 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 write_reg(DS1308_SEC_ADD, ptrvalues, 7) == 0;
}
bool read_date_time(gnss_precise_time &gt) {
uint8_t ptrvalues[7];
bool ret = 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 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 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);
}
}