Sensorian  1.0
C API Reference Guide Library
MCP79410.c
Go to the documentation of this file.
1 /****************************************************************************
2  * Copyright (C) 2015 Sensorian
3  * *
4  * This file is part of Sensorian. *
5  * *
6  * Sensorian is free software: you can redistribute it and/or modify it *
7  * under the terms of the GNU Lesser General Public License as published *
8  * by the Free Software Foundation, either version 3 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * Sensorian is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with Sensorian. *
18  * If not, see <http://www.gnu.org/licenses/>. *
19  ****************************************************************************/
20 
28 #include "MCP79410.h"
29 #include "i2c.h"
30 #include <time.h>
31 #include <stdlib.h>
32 
33 //#define __DEBUG_RTCC__
34 
38 
44 {
45  MCP79410_SetHourFormat(H24); //Set hour format to military time standard
46  MCP79410_EnableVbat(); //Enable battery backup
47 
48  time_t t = time(NULL);
49  struct tm tm = *localtime(&t);
50  RTCC_Struct curr_time = {tm.tm_sec,tm.tm_min,tm.tm_hour,tm.tm_wday,tm.tm_mday,tm.tm_mon+1, ((tm.tm_year+1900)-2000)};
51  #ifdef __DEBUG_RTCC__
52  printf("MCP79410_Initialize DEBUG now: %d-%d-%d %d:%d:%d\n", tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
53  #endif
54  MCP79410_SetTime(&curr_time);
55  MCP79410_EnableOscillator(); //Start clock by enabling oscillator
56 }
57 
63 {
64  unsigned char ST_bit = MCP79410_Read(DAY); //Read day + OSCON bit
65  ST_bit = ST_bit | START_32KHZ;
66  MCP79410_Write(SEC,ST_bit); //START bit is located in the Sec register
67 }
68 
74 {
75  unsigned char ST_bit = MCP79410_Read(DAY); //Read day + OSCON bit
76  ST_bit = ST_bit & ~START_32KHZ;
77  MCP79410_Write(SEC,ST_bit); //START bit is located in the Sec regist
78 }
79 
84 unsigned char MCP79410_IsRunning(void)
85 {
86  unsigned char mask = MCP79410_Read(DAY);
87 
88  if((mask & OSCRUN) == OSCRUN) //If oscillator = already running, do nothing.
89  {
90  return TRUE;
91  }else{
92  return FALSE;
93  }
94 }
95 
101 {
102  RTCC_Struct *current_time = (RTCC_Struct *) malloc(sizeof(RTCC_Struct));
103 
104  current_time->sec = MCP79410_bcd2dec( MCP79410_Read(SEC) & (~START_32KHZ));
105  current_time->min = MCP79410_bcd2dec( MCP79410_Read(MIN));
106 
107  unsigned char hour_t = MCP79410_Read(HOUR);
108 
109  hour_t = ((hour_t & HOUR_12) == HOUR_12)? (hour_t & 0x1F) : (hour_t & 0x3F); //hour is in 24 hour format
110 
111  current_time->hour = MCP79410_bcd2dec(hour_t);
113  current_time->date = MCP79410_bcd2dec( MCP79410_Read(DATE));
114  current_time->month = MCP79410_bcd2dec( MCP79410_Read(MNTH) & ~(LPYR));
115  current_time->year = MCP79410_bcd2dec( MCP79410_Read(YEAR));
116 
117  return current_time;
118 }
119 
126 {
127  unsigned char sec = MCP79410_Read(SEC); //Seconds
128  unsigned char min = 0; //Minutes
129  unsigned char hour = MCP79410_Read(HOUR); //Hours
130  unsigned char weekday = MCP79410_Read(DAY); //Weekday
131  unsigned char date = 0; //Date
132  unsigned char month = MCP79410_Read(MNTH); //Month
133  unsigned char year = 0; //Year
134 
135  if((sec & START_32KHZ) == START_32KHZ) //Seconds register
136  {
137  sec = MCP79410_dec2bcd(time->sec)| START_32KHZ;
138  }else{
139  sec = MCP79410_dec2bcd(time->sec);
140  }
141 
142  min = MCP79410_dec2bcd(time->min); //Minutes
143 
144  if(( hour & HOUR_12) == HOUR_12) //Hour register
145  {
146  hour = MCP79410_dec2bcd(time->hour) | HOUR_12;
147  }else{
148  hour = MCP79410_dec2bcd(time->hour);
149  }
150 
151  if(( hour & PM) == PM)
152  {
153  hour = hour | PM;
154  }
155 
156  weekday &= 0x38; //Mask 3 upper bits
157  weekday |= MCP79410_dec2bcd(time->weekday) ; //Weekday
158 
159  date = MCP79410_dec2bcd(time->date); //Date
160 
161  if((month & LPYR) == LPYR) //Month
162  {
163  month = MCP79410_dec2bcd(time->month) | LPYR;
164  }else{
165  month = MCP79410_dec2bcd(time->month);
166  }
167 
168  year = MCP79410_dec2bcd(time->year); //Year
169 
170  MCP79410_Write(SEC,sec);
171  MCP79410_Write(MIN,min);
172  MCP79410_Write(HOUR,hour);
173  MCP79410_Write(DAY,weekday);
174  MCP79410_Write(DATE,date);
175  MCP79410_Write(MNTH,month);
176  MCP79410_Write(YEAR,year);
177 }
178 
185 {
186  MCP79410_DisableOscillator(); //Diable clock
187  unsigned char Format_bit = MCP79410_Read(HOUR); //Read hour format bit
188  if(format == H24)
189  {
190  Format_bit &= ~HOUR_FORMAT; //Set format to H12 (military)
191  }else{
192  Format_bit |= HOUR_FORMAT; //Set format to H12
193  }
194  MCP79410_Write(HOUR,Format_bit); //START bit is located in the Sec register
195  MCP79410_EnableOscillator(); //Enable clock
196 }
197 
203 void MCP79410_SetPMAM(PMAM_t meridian)
204 {
205  MCP79410_DisableOscillator(); //Diable clock
206  unsigned char PMAM_bit = MCP79410_Read(HOUR); //Read meridian bit
207  if(meridian == AMT)
208  {
209  PMAM_bit &= ~PM; //Set AM
210  }else{
211  PMAM_bit |= PM; //Set PM
212  }
213  MCP79410_Write(HOUR,PMAM_bit); //Update PM/AM meridian bit
214  MCP79410_EnableOscillator(); //Enable clock
215 }
216 
223 {
224  unsigned char ctrl_bits = MCP79410_Read(CTRL);
225  if(alarm == ZERO)
226  {
227  ctrl_bits |= ALM_0;
228  MCP79410_Write(CTRL,ctrl_bits);
229  }else{
230  ctrl_bits |= ALM_1;
231  MCP79410_Write(CTRL,ctrl_bits);
232  }
233 }
234 
241 {
242  unsigned char ctrl_bits = MCP79410_Read(CTRL);
243  if(alarm == ZERO)
244  {
245  ctrl_bits &= ~ALM_0;
246  MCP79410_Write(CTRL,ctrl_bits);
247  }else{
248  ctrl_bits &= ~ALM_1;
249  MCP79410_Write(CTRL,ctrl_bits);
250  }
251 }
252 
259 {
260  AlarmStatus_t status;
261  unsigned char temp;
262  if(alarm == ZERO)
263  {
264  temp = MCP79410_Read(ALM0WDAY); //Read WKDAY register for ALRAM 0
265  }else{
266  temp = MCP79410_Read(ALM1WDAY); //Read WKDAY register for ALRAM 1
267  }
268  return status = (AlarmStatus_t)((temp & ALMx_IF) == ALMx_IF)? SET : NOT_SET;
269 }
270 
277 {
278  unsigned char temp;
279  if(alarm == ZERO)
280  {
281  temp = MCP79410_Read(ALM0WDAY); //Read WKDAY register for ALRAM 0
282  temp &= (~ALMx_IF); //Clear 4-th bit
283  MCP79410_Write(ALM0WDAY,temp); //Enable backup battery mode
284  }else{
285  temp = MCP79410_Read(ALM1WDAY); //Read WKDAY register for ALRAM 1
286  temp &= (~ALMx_IF); //Clear 4-th bit
287  MCP79410_Write(ALM1WDAY,temp); //Enable backup battery mode
288  }
289 }
290 
298 {
299  unsigned char sec = MCP79410_dec2bcd(time->sec);
300  unsigned char min = MCP79410_dec2bcd(time->min);
301  unsigned char hour = MCP79410_dec2bcd(time->hour);
302  unsigned char weekday = MCP79410_dec2bcd(time->weekday);
303  unsigned char date = MCP79410_dec2bcd(time->date);
304  unsigned char month = MCP79410_dec2bcd(time->month);
305 
306  if(alarm == ZERO)
307  {
309  MCP79410_Write(ALM0MIN,min);
310  MCP79410_Write(ALM0HR,hour);
311  MCP79410_Write(ALM0WDAY,weekday);
312  MCP79410_Write(ALM0DATE,date);
313  MCP79410_Write(ALM0MTH,month);
314  }else{
316  MCP79410_Write(ALM1MIN,min);
317  MCP79410_Write(ALM1HR,hour);
318  MCP79410_Write(ALM1WDAY,weekday);
319  MCP79410_Write(ALM1DATE,date);
320  MCP79410_Write(ALM1MTH,month);
321  }
322 }
323 
332 {
333  unsigned char Polarity_bit = 0;
334 
335  if(alarm == ZERO)
336  {
337  Polarity_bit = MCP79410_Read(ALM0WDAY); //Read hour format bit
338  }
339  else{
340  Polarity_bit = MCP79410_Read(ALM1WDAY); //Read hour format bit
341  }
342 
343  if(MFP_pol == LOW)
344  {
345  Polarity_bit &= ~ALMx_POL; //Set MFP LOW
346  }else{
347  Polarity_bit |= ALMx_POL; //Set MFP HIGH
348  }
349 
350  if(alarm == ZERO)
351  {
352  MCP79410_Write(ALM0WDAY,Polarity_bit); //Update polarity bit for Alarm 0
353  }else{
354  MCP79410_Write(ALM1WDAY,Polarity_bit); //Update polarity bit for Alarm 1
355  }
356 }
357 
365 {
366  unsigned char AlarmRegister = 0;
367  if(alarm == ZERO)
368  {
369  AlarmRegister = ALM0WDAY;
370  }else{
371  AlarmRegister = ALM1WDAY;
372  }
373 
374  unsigned char match_bits = MCP79410_Read(AlarmRegister);
375 
376  switch(match)
377  {
378  case SECONDS_MATCH :
379  match_bits &= ~(ALM0MSK2|ALM0MSK1|ALM0MSK0);
380  MCP79410_Write(AlarmRegister,match_bits); //Minutes match
381  break;
382  case MINUTES_MATCH :
383  match_bits |= ALM0MSK0;
384  MCP79410_Write(AlarmRegister,match_bits); //Minutes match
385  break;
386  case HOURS_MATCH :
387  match_bits |= ALM0MSK1;
388  MCP79410_Write(AlarmRegister,match_bits); //Hours match
389  break;
390  case WEEKDAY_MATCH :
391  match_bits |= ALM0MSK1|ALM0MSK0;
392  MCP79410_Write(AlarmRegister,match_bits); //Day of week match
393  break;
394  case DATE_MATCH :
395  match_bits |= ALM0MSK2;
396  MCP79410_Write(AlarmRegister,match_bits); //Date match
397  break;
398  case FULL_DATE_MATCH :
399  match_bits |= ALM0MSK2|ALM0MSK1|ALM0MSK0;
400  MCP79410_Write(AlarmRegister,match_bits); //Sec, Minutes Hours, Date match
401  break;
402  default :
403  match_bits |= ALM0MSK0;
404  MCP79410_Write(AlarmRegister,match_bits); //Minutes match
405  break;
406  }
407 }
408 
415 {
416  unsigned char MFP_bits = MCP79410_Read(CTRL);
417 
418  switch(mode)
419  {
420  case GPO : //For GPO clear SQWEN, ALM0EN, ALM1EN
421  MFP_bits &= ~(SQWEN|ALM_0|ALM_1);
422  MCP79410_Write(CTRL,MFP_bits);
423  break;
424  case ALARM_INTERRUPT : //For ALARM Interrupts clear SQWEN and set either ALM0EN or ALM1EN
425  MFP_bits &= SQWEN;
426  MFP_bits |= ALM_0;
427  MCP79410_Write(CTRL,MFP_bits);
428  break;
429  case SQUARE_WAVE : //For SQUARE WAVE set SQWEN
430  MFP_bits &= ~(ALM_0|ALM_1);
431  MFP_bits |= SQWEN;
432  MCP79410_Write(CTRL,MFP_bits);
433  break;
434  default: //ALARM Interrupts
435  MFP_bits &= SQWEN;
436  MFP_bits |= ALM_0;
437  MCP79410_Write(CTRL,MFP_bits);
438  break;
439  }
440 }
441 
448 {
449  unsigned char gpo_bit = MCP79410_Read(CTRL); //General Purpose Output mode only available when (SQWEN = 0, ALM0EN = 0, and ALM1EN = 0):
450 
451  if(status == LOW)
452  {
453  gpo_bit = OUT_PIN; //MFP signal level is logic low
454  MCP79410_Write(CTRL,gpo_bit);
455  }else{ //MFP signal level is logic high
456  gpo_bit |= OUT_PIN;
457  MCP79410_Write(CTRL,gpo_bit);
458  }
459 }
460 
465 unsigned char MCP79410_CheckPowerFailure(void)
466 {
467  unsigned char PowerFailure_bit = MCP79410_Read(DAY); //Read meridian bit
468  unsigned char PowerFail;
469 
470  if((PowerFailure_bit & PWRFAIL) == PWRFAIL)
471  {
472  PowerFail = TRUE;
473  }else{
474  PowerFail = FALSE;
475  }
476  PowerFailure_bit &= ~PWRFAIL; //Clear Power failure bit
477  MCP79410_Write(DAY,PowerFailure_bit); //Update PM/AM meridian bit
478 
479  return PowerFail;
480 }
481 
486 unsigned char MCP79410_IsVbatEnabled(void)
487 {
488  unsigned char temp;
489  temp = MCP79410_Read(DAY); //The 3rd bit of the RTCC_RTCC day register controls VBATEN
490 
491  if((temp & VBATEN) == VBATEN)
492  {
493  return TRUE;
494  }else{
495  return FALSE;
496  }
497 }
498 
504 {
505  unsigned char temp;
506  temp = MCP79410_Read(DAY); //The 3rd bit of the RTCC_RTCC day register controls VBATEN
507  temp = (temp | VBATEN); //Set 3rd bit to enable backup battery mode
508  MCP79410_Write(DAY,temp); //Enable backup battery mode
509 }
510 
516 {
517  unsigned char temp;
518  temp = MCP79410_Read(DAY); //The 3rd bit of the RTCC_RTCC day register controls VBATEN
519  temp = (temp & VBAT_DIS); //Clear 3rd bit to disable backup battery mode
520  MCP79410_Write(DAY,temp); //Enable backup battery mode
521 }
522 
528 {
529  RTCC_Struct *powerup_time = (RTCC_Struct *) malloc(sizeof(RTCC_Struct));
530 
531  powerup_time->min = MCP79410_bcd2dec( MCP79410_Read(PWRUPMIN));
532  powerup_time->hour = MCP79410_bcd2dec( MCP79410_Read(PWRUPHOUR));
533  powerup_time->date = MCP79410_bcd2dec( MCP79410_Read(PWRUPDATE));
534  powerup_time->month = MCP79410_bcd2dec( MCP79410_Read(PWRUPMTH));
535 
536  return powerup_time;
537 }
538 
544 {
545  RTCC_Struct *powerdown_time = (RTCC_Struct *) malloc(sizeof(RTCC_Struct));
546 
547  powerdown_time->min = MCP79410_bcd2dec( MCP79410_Read(PWRDNMIN));
548  powerdown_time->hour = MCP79410_bcd2dec( MCP79410_Read(PWRDNHOUR));
549  powerdown_time->date = MCP79410_bcd2dec( MCP79410_Read(PWRDNDATE));
550  powerdown_time->month = MCP79410_bcd2dec( MCP79410_Read(PWRDNMTH));
551 
552  return powerdown_time;
553 }
554 
560 unsigned char MCP79410_dec2bcd(unsigned char num)
561 {
562  return ((num/10 * 16) + (num % 10));
563 }
564 
570 unsigned char MCP79410_bcd2dec(unsigned char num)
571 {
572  return ((num/16 * 10) + (num % 16));
573 }
574 
576 
583 void MCP79410_Write(unsigned char rtcc_reg, unsigned char time_var)
584 {
585  I2C_WriteByteRegister(rtcc_reg,time_var);
586 }
587 
593 unsigned char MCP79410_Read(unsigned char rtcc_reg)
594 {
595  return I2C_ReadByteRegister(rtcc_reg);
596 }
#define PM
Definition: MCP79410.h:95
I2C driver.
#define MNTH
Definition: MCP79410.h:63
Definition: MCP79410.h:172
Definition: MCP79410.h:167
void MCP79410_SetMFP_GPOStatus(Polarity_t status)
This function sets the MFP output logic level when the pin is configured as GPO.
Definition: MCP79410.c:447
#define OUT_PIN
Definition: MCP79410.h:97
unsigned char MCP79410_dec2bcd(unsigned char num)
Convert Binary Coded Decimal (BCD) to Decimal.
Definition: MCP79410.c:560
#define OSCRUN
Definition: MCP79410.h:117
#define START_32KHZ
Definition: MCP79410.h:122
void MCP79410_EnableAlarm(Alarm_t alarm)
This function sets the alarm time.
Definition: MCP79410.c:222
#define ALM0MSK1
Definition: MCP79410.h:135
#define PWRDNMTH
Definition: MCP79410.h:86
void MCP79410_SetAlarmMatch(Match_t match, Alarm_t alarm)
Alarm Asserts on Match on seconds, minutes ,hours depending on match parameter.
Definition: MCP79410.c:364
#define DATE
Definition: MCP79410.h:62
void MCP79410_DisableVbat(void)
This function disables the backup battery functionality.
Definition: MCP79410.c:515
#define FALSE
Definition: EEPROM.h:70
void MCP79410_DisableOscillator(void)
Disables the clock oscillator.The RTCC does not operate once the oscillator is stopped.
Definition: MCP79410.c:73
#define PWRUPDATE
Definition: MCP79410.h:90
#define ALMx_IF
Definition: MCP79410.h:115
enum Format Format_t
MCP79410 driver header.
void MCP79410_Write(unsigned char rtcc_reg, unsigned char time_var)
The below function writes a data byte in the I2C RTCC.
Definition: MCP79410.c:583
unsigned char year
Month.
Definition: MCP79410.h:151
#define HOUR_FORMAT
Definition: MCP79410.h:96
#define ALM0MSK0
Definition: MCP79410.h:136
#define ALM0HR
Definition: MCP79410.h:71
#define ALM1MTH
Definition: MCP79410.h:81
#define ALM1HR
Definition: MCP79410.h:78
#define CTRL
Definition: MCP79410.h:65
unsigned char MCP79410_IsRunning(void)
Checks if the chip clock is running.
Definition: MCP79410.c:84
void MCP79410_SetTime(RTCC_Struct *time)
This function initializes the RTCC with a specific time contained in the time structure.
Definition: MCP79410.c:125
#define SQWEN
Definition: MCP79410.h:98
#define ALM1WDAY
Definition: MCP79410.h:79
#define PWRDNHOUR
Definition: MCP79410.h:84
#define ALM0DATE
Definition: MCP79410.h:73
unsigned char date
Weekday.
Definition: MCP79410.h:149
#define PWRUPMIN
Definition: MCP79410.h:88
#define HOUR_12
Definition: MCP79410.h:124
unsigned char MCP79410_CheckPowerFailure(void)
This function checks if there was a power failure.
Definition: MCP79410.c:465
Definition: MCP79410.h:157
void MCP79410_SetAlarmMFPPolarity(Polarity_t MFP_pol, Alarm_t alarm)
This function sets the MFP polarity either high or low.
Definition: MCP79410.c:331
RTCC_Struct * MCP79410_GetTime(void)
The function returns a time structure with the current time from the RTCC.
Definition: MCP79410.c:100
#define DAY
Definition: MCP79410.h:60
#define PWRDNDATE
Definition: MCP79410.h:85
unsigned char weekday
Hours, (Format used : Standard / Military)
Definition: MCP79410.h:148
unsigned char MCP79410_Read(unsigned char rtcc_reg)
Definition: MCP79410.c:593
#define ALM0MSK2
Definition: MCP79410.h:134
#define ALM1DATE
Definition: MCP79410.h:80
#define ALM0MIN
Definition: MCP79410.h:70
unsigned char month
Date of the month.
Definition: MCP79410.h:150
#define PWRUPMTH
Definition: MCP79410.h:91
unsigned char sec
Definition: MCP79410.h:145
void I2C_WriteByteRegister(unsigned char reg, unsigned char data)
Writes a byte value to a register address.
Definition: i2c.c:66
void MCP79410_EnableOscillator(void)
Enables the clock oscillator. This must be enabled in order for the RTCC to run.
Definition: MCP79410.c:62
#define ALM1MIN
Definition: MCP79410.h:77
#define ALM0WDAY
Definition: MCP79410.h:72
void MCP79410_ClearInterruptFlag(Alarm_t alarm)
Clears the interrupt alarm flag.
Definition: MCP79410.c:276
enum MFP_POL Polarity_t
AlarmStatus_t MCP79410_GetAlarmStatus(Alarm_t alarm)
This function gets the status of the alarm interrupt flag.
Definition: MCP79410.c:258
enum Alarm Alarm_t
#define VBAT_DIS
Definition: MCP79410.h:120
#define ALM1SEC
Definition: MCP79410.h:76
void MCP79410_Initialize(void)
Initializes the RTCC with the system time.
Definition: MCP79410.c:43
void MCP79410_SetHourFormat(Format_t format)
This function sets the hour format.
Definition: MCP79410.c:184
#define PWRUPHOUR
Definition: MCP79410.h:89
#define ALM_0
Definition: MCP79410.h:100
#define LPYR
Definition: MCP79410.h:126
void MCP79410_EnableVbat(void)
This function enables backup battery mode.
Definition: MCP79410.c:503
#define SEC
Definition: MCP79410.h:57
#define VBATEN
Definition: MCP79410.h:119
#define ALM_1
Definition: MCP79410.h:101
void MCP79410_SetAlarmTime(RTCC_Struct *time, Alarm_t alarm)
This function sets the alarm time for one of the two alarms.
Definition: MCP79410.c:297
enum Match Match_t
#define PWRDNMIN
Definition: MCP79410.h:83
#define ALM0MTH
Definition: MCP79410.h:74
#define YEAR
Definition: MCP79410.h:64
#define TRUE
Definition: EEPROM.h:69
#define MIN
Definition: MCP79410.h:58
Definition: MCP79410.h:162
Definition: MCP79410.h:182
unsigned char min
Seconds.
Definition: MCP79410.h:146
RTCC_Struct * MCP79410_GetPowerDownTime(void)
This function returns the power-down time of the RTCC.
Definition: MCP79410.c:543
unsigned char I2C_ReadByteRegister(char reg)
Reads a byte from a register.
Definition: i2c.c:122
unsigned char hour
Minutes.
Definition: MCP79410.h:147
unsigned char MCP79410_IsVbatEnabled(void)
This function checks if battery mode is enabled.
Definition: MCP79410.c:486
#define ALMx_POL
Definition: MCP79410.h:108
enum MFP_MODE MFP_t
enum AlarmStatus AlarmStatus_t
RTCC_Struct * MCP79410_GetPowerUpTime(void)
This function returns the power-up time of the RTCC.
Definition: MCP79410.c:527
enum PMAM PMAM_t
#define PWRFAIL
Definition: MCP79410.h:118
void MCP79410_DisableAlarm(Alarm_t alarm)
This function disables one of the two alarms.
Definition: MCP79410.c:240
void MCP79410_SetMFP_Functionality(MFP_t mode)
This function sets the MFP pin mode.
Definition: MCP79410.c:414
#define ALM0SEC
Definition: MCP79410.h:69
#define HOUR
Definition: MCP79410.h:59
void MCP79410_SetPMAM(PMAM_t meridian)
This function sets the meridian mode.
Definition: MCP79410.c:203
unsigned char MCP79410_bcd2dec(unsigned char num)
Convert Binary Coded Decimal (BCD) to Decimal.
Definition: MCP79410.c:570