InetrfaceProducts NXP / PCF2127

Dependents:   PCF2127_Demo PCF2127_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCF2127.cpp Source File

PCF2127.cpp

00001 /*
00002  *  PCF2127 library
00003  *
00004  *  @author     Akifumi (Tedd) OKANO, NXP Semiconductors
00005  *  @version    1.8
00006  *  @date       10-Dec-2014
00007  *
00008  *  PCF2127 is a "real time clock (RTC)" module which is including a Xtal and TCXO
00009  *  http://www.nxp.com/products/interface_and_connectivity/real_time_clocks/rtcs_with_temp_compensation/series/PCF2127.html
00010  *
00011  *  RTC initializing part is ported from..
00012  *    http://mbed.org/users/roen/notebook/real-time/
00013  *
00014  *  This code is refined version of..
00015  *    http://developer.mbed.org/users/okano/code/NXP_PCF2127A/
00016  */
00017 
00018 #include    "mbed.h"
00019 #include    "PCF2127.h"
00020 
00021 #define     PCF2127_I2C_SLAVE_ADDRESS   0xA2
00022 
00023 PCF2127::PCF2127( PinName sda, PinName sdl, char vControl_1, char vControl_2, char vControl_3, char vCLKOUT_ctl )
00024     : i2c_p( new I2C( sda, sdl ) ), i2c( *i2c_p ), device_address( PCF2127_I2C_SLAVE_ADDRESS )
00025 {
00026     init( vControl_1, vControl_2, vControl_3, vCLKOUT_ctl );
00027 }
00028 
00029 PCF2127::PCF2127( I2C &i2c_, char vControl_1, char vControl_2, char vControl_3, char vCLKOUT_ctl )
00030     : i2c_p( NULL ), i2c( i2c_ ), device_address( PCF2127_I2C_SLAVE_ADDRESS )
00031 {
00032     init( vControl_1, vControl_2, vControl_3, vCLKOUT_ctl );
00033 }
00034 
00035 PCF2127::~PCF2127()
00036 {
00037     if ( NULL != i2c_p )
00038         delete  i2c_p;
00039 }
00040 
00041 int PCF2127::init( char vControl_1, char vControl_2, char vControl_3, char vCLKOUT_ctl )
00042 {
00043     char    data[ 4 ];
00044     int     err;
00045 
00046     data[ 0 ]   = Control_1; //  access start register address
00047     data[ 1 ]   = vControl_1;
00048     data[ 2 ]   = vControl_2;
00049     data[ 3 ]   = vControl_3;
00050 
00051     err     = i2c.write( device_address, data, sizeof( data ) );
00052     err    |= set_register( CLKOUT_ctl, vCLKOUT_ctl );
00053 
00054     return ( err ? I2C_ACCESS_FAIL : NO_ERROR );
00055 }
00056 
00057 int PCF2127::is_init_required( void )
00058 {
00059     return ( read_register( Seconds ) & 0x80 ? true : false );
00060 }
00061 
00062 int PCF2127::set_time( struct tm *dtp )
00063 {
00064     char        buf[ 8 ];
00065     char        err;
00066 
00067     buf[ 0 ]    = Seconds;
00068     buf[ 1 ]    = i2bcd( dtp->tm_sec  );
00069     buf[ 2 ]    = i2bcd( dtp->tm_min  );
00070     buf[ 3 ]    = i2bcd( dtp->tm_hour );
00071     buf[ 4 ]    = i2bcd( dtp->tm_mday );
00072     buf[ 5 ]    = i2bcd( dtp->tm_wday );
00073     buf[ 6 ]    = i2bcd( dtp->tm_mon  + 1   );
00074     buf[ 7 ]    = i2bcd( dtp->tm_year - 100 );
00075 
00076     err = i2c.write( device_address, buf, 8 );
00077 
00078     return ( err ? I2C_ACCESS_FAIL : NO_ERROR );
00079 }
00080 
00081 int PCF2127::set_time( time_t *tp )
00082 {
00083     return ( set_time( localtime( tp ) ) );
00084 }
00085 
00086 int PCF2127::set_time( char *s )
00087 {
00088     //  The time information should be given in format of "YYYY MM DD HH MM SS"
00089 
00090     struct tm   dt, *dtp;
00091 
00092     dtp = &dt;
00093 
00094     sscanf( s, "%d %d %d %d %d %d", &(dtp->tm_year), &(dtp->tm_mon), &(dtp->tm_mday), &(dtp->tm_hour), &(dtp->tm_min), &(dtp->tm_sec) );
00095     printf( "%02d/%02d/%02d - %02d:%02d:%02d\r\n", (dtp->tm_year), (dtp->tm_mon), (dtp->tm_mday), (dtp->tm_hour), (dtp->tm_min), (dtp->tm_sec) );
00096 
00097     // adjust for tm structure required values
00098     dtp->tm_year = dtp->tm_year - 1900;
00099     dtp->tm_mon  = dtp->tm_mon - 1;
00100 
00101     return ( set_time( dtp ) );
00102 }
00103 
00104 time_t PCF2127::time( time_t *tp )
00105 {
00106     struct tm   dt, *dtp;
00107     time_t      t;
00108     char        buf[ 8 ];
00109 
00110     dtp = &dt;
00111 
00112     buf[ 0 ]    = Seconds;  //  read start register address
00113 
00114     if ( i2c.write( device_address, buf, 1 ) )
00115         return ( TIME_FUNC_ERROR );
00116 
00117     if ( i2c.read( device_address, buf, 7 ) )
00118         return ( TIME_FUNC_ERROR );
00119 
00120     dtp->tm_sec     = bcd2i( buf[ 0 ] );
00121     dtp->tm_min     = bcd2i( buf[ 1 ] );
00122     dtp->tm_hour    = bcd2i( buf[ 2 ] );
00123     dtp->tm_mday    = bcd2i( buf[ 3 ] );
00124     dtp->tm_wday    = bcd2i( buf[ 4 ] );
00125     dtp->tm_mon     = bcd2i( buf[ 5 ] ) - 1;
00126     dtp->tm_year    = bcd2i( buf[ 6 ] ) + 100;
00127 
00128     t   = mktime( dtp );
00129 
00130     if ( tp )
00131         *tp  = t;
00132 
00133     return( t );
00134 }
00135 
00136 int PCF2127::set_alarm( char addr, char s )
00137 {
00138     char    v;
00139 
00140     v   = i2bcd( s );
00141 
00142     return ( set_register( addr, v ) );
00143 }
00144 
00145 int PCF2127::clear_intr( void )
00146 {
00147     return ( set_register( Control_2, 0x00 ) );
00148 }
00149 
00150 int PCF2127::RAM_write( int address, char *p, int size )
00151 {
00152     char    b[ size + 1 ];
00153 
00154     b[ 0 ]  = RAM_wrt_cmd;
00155 
00156     for ( int i = 1; i <= size; i++ )
00157         b[ i ]  = *p++;
00158 
00159     if ( set_RAM_address( address ) )
00160         return ( I2C_ACCESS_FAIL );
00161 
00162     return ( i2c.write( device_address, b, sizeof( b ) ) ? I2C_ACCESS_FAIL : NO_ERROR );
00163 }
00164 
00165 int PCF2127::RAM_read( int address, char *p, int size )
00166 {
00167     char    b   = RAM_rd_cmd;
00168 
00169     if ( set_RAM_address( address ) )
00170         return ( I2C_ACCESS_FAIL );
00171 
00172     if ( i2c.write( device_address, &b, 1 ) )
00173         return ( I2C_ACCESS_FAIL );
00174 
00175     return ( i2c.read( device_address, p, size ) ? I2C_ACCESS_FAIL : NO_ERROR );
00176 }
00177 
00178 
00179 int PCF2127::set_RAM_address( char address )
00180 {
00181     char    b[ 3 ];
00182 
00183     b[ 0 ]  = RAM_addr_MSB;
00184     b[ 1 ]  = (address >> 8) & 0x1;
00185     b[ 2 ]  = address & 0xFF;
00186 
00187     return ( i2c.write( device_address, b, sizeof( b ) ) );
00188 }
00189 
00190 int PCF2127::set_register( char addr, char data )
00191 {
00192     char    b[ 2 ];
00193 
00194     b[ 0 ]    = addr;
00195     b[ 1 ]    = data;
00196 
00197     return ( i2c.write( device_address, b, sizeof( b ) ) );
00198 }
00199 
00200 int PCF2127::read_register( char addr )
00201 {
00202     char    data;
00203 
00204     data    = addr;
00205     i2c.write( device_address, &data, 1 );
00206     i2c.read( device_address, &data, 1 );
00207 
00208     return ( data );
00209 }
00210 
00211 char PCF2127::i2bcd( char n )
00212 {
00213     return ( ((n / 10) << 4) | (n % 10) );
00214 }
00215 
00216 char PCF2127::bcd2i( char bcd )
00217 {
00218     return ( ((bcd >> 4) * 10) + (bcd & 0x0F) );
00219 }