|
|
/*
|
|
|
* 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.
|
|
|
*/
|
|
|
void 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
|
|
|
*/
|
|
|
void 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();
|
|
|
}
|
|
|
|
|
|
/*!
|
|
|
* \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
|
|
|
*/
|
|
|
void set_time(tmElements_t &tm) {
|
|
|
|
|
|
Wire.beginTransmission(DS1308_CTRL_ID);
|
|
|
// start with Clock Control and the Seconds register
|
|
|
Wire.write(DS1308_SEC_ADD);
|
|
|
Wire.write((uint8_t)0x80); // Set clock control bit to 1. This stops the clock
|
|
|
Wire.write(dec2bcd(tm.Minute));
|
|
|
Wire.write(dec2bcd(tm.Hour)); // sets 24 hour format
|
|
|
Wire.write(dec2bcd(tm.Wday));
|
|
|
Wire.write(dec2bcd(tm.Day));
|
|
|
Wire.write(dec2bcd(tm.Month));
|
|
|
Wire.write(dec2bcd(tmYearToY2k(tm.Year)));
|
|
|
Wire.endTransmission();
|
|
|
|
|
|
Wire.beginTransmission(DS1308_CTRL_ID);
|
|
|
// Address the Clock Control and the Seconds register
|
|
|
Wire.write(DS1308_SEC_ADD);
|
|
|
// Set clock control bit to 0 and number of seconds. This starts the clock
|
|
|
Wire.write(dec2bcd(tm.Second));
|
|
|
Wire.endTransmission();
|
|
|
}
|
|
|
|
|
|
/*!
|
|
|
* \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.
|
|
|
*/
|
|
|
void activate_pps(void) {
|
|
|
Wire.beginTransmission(DS1308_CTRL_ID);
|
|
|
Wire.write(DS1308_CTL_ADD);
|
|
|
// CLKIN com 1Hz de salida (1PPS)
|
|
|
Wire.write(0<<ECLK|0<<OSF|1<<SQWE|0<<LOS|0<<BBCLK|0<<RS1|0<<RS0);
|
|
|
Wire.endTransmission();
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
/*!
|
|
|
* \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_ram(uint8_t regaddr, uint8_t *pbuf, uint8_t cnt) {
|
|
|
|
|
|
uint8_t nread=0;
|
|
|
while( (cnt > 0) && ( regaddr < DS1308_RAM_REGS ) ) {
|
|
|
Wire.beginTransmission(DS1308_CTRL_ID);
|
|
|
Wire.write(regaddr+DS1308_RAM_BASE);
|
|
|
Wire.endTransmission();
|
|
|
Wire.requestFrom((uint8_t)DS1308_CTRL_ID, cnt);
|
|
|
while(Wire.available() && (cnt > 0) && (regaddr < DS1308_RAM_REGS) ) {
|
|
|
pbuf[nread] = Wire.read();
|
|
|
nread++; cnt--; regaddr++;
|
|
|
} /* while */
|
|
|
}
|
|
|
return (nread);
|
|
|
}
|
|
|
|
|
|
/*!
|
|
|
* \fn write_ram
|
|
|
* \brief Escribe un valor en la memoria RAM interna del RTC DS1308, en la
|
|
|
* direccion especificada.
|
|
|
* \param addr direccion relativa a la RAM (0 es la primera) del registro
|
|
|
* en DS1308.
|
|
|
* \param val valor que se desea escribir en el registro.
|
|
|
* \return estatus
|
|
|
* 0 success
|
|
|
* 2 error: address send, nack received
|
|
|
* 3 error: data send, nack received
|
|
|
* 4 other twi error
|
|
|
*/
|
|
|
uint8_t write_ram(uint8_t regaddr, uint8_t val) {
|
|
|
|
|
|
uint8_t rc=0;
|
|
|
if (regaddr >= DS1308_RAM_REGS) return (DS1308_RAM_REGS); // 0 thru 51
|
|
|
Wire.beginTransmission(DS1308_CTRL_ID);
|
|
|
Wire.write(regaddr+DS1308_RAM_BASE);
|
|
|
Wire.write(val);
|
|
|
rc = Wire.endTransmission();
|
|
|
return(rc);
|
|
|
}
|
|
|
|
|
|
/*!
|
|
|
* \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_ram(uint8_t regaddr, const uint8_t *pbuf,uint8_t cnt) {
|
|
|
|
|
|
uint8_t nbytes, rc=0;
|
|
|
if (regaddr >= DS1308_RAM_REGS) return (DS1308_RAM_REGS); // 0 thru 55
|
|
|
if (regaddr+cnt > DS1308_RAM_REGS) cnt = DS1308_RAM_REGS-regaddr;
|
|
|
while (cnt > 0) {
|
|
|
nbytes = min(cnt, BUFFER_LENGTH-1);
|
|
|
Wire.beginTransmission(DS1308_CTRL_ID);
|
|
|
Wire.write(regaddr+DS1308_RAM_BASE);
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
|
|
|
}// end namespace rtc
|
|
|
|