rtc1308.cpp
184 lines
| 5.1 KiB
| text/x-c
|
CppLexer
|
r132 | /* | ||
* rtc1308.cpp | ||||
* | ||||
* Created on: Nov 4, 2014 | ||||
* Author: Alan Aguilar Sologuren | ||||
*/ | ||||
#include <rtc1308.h> | ||||
|
r140 | #include <Wire.h> | ||
|
r132 | |||
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 | ||||