⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dallasdate.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
字号:
/* * dallasdate.c: * Code to support the DALLAS DS1743W Timekeeping RAM plus the hooks to * allow TFS to timestamp files.  The function tfsTimeEnable() must be * called to setup the connection between TFS and the DS1743W. * * Applicable to DS1743W and DS1746WP.  Probably also works with other * Dallas timekeepers, but the above two are the only ones I've tested  * it with.  This code is assumed to be compiled with the DATEREGBASE * value defined elsewhere.  This value is the address at which the code * is to access the 8-byte register map that contains the time/date * information. * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com *  Phone:              908-582-2351 */#include "config.h"#include "stddefs.h"#include "genlib.h"#include "tfs.h"#include "tfsprivate.h"#include "cli.h"#ifndef DATEREGBASE#error DATEREGBASE not defined#endif#define WRITE   0x80        /* part of 'cent' member */#define READ    0x40        /* part of 'cent' member */#define BF      0x80        /* part of 'wday' member */#define FT      0x40        /* part of 'wday' member */#define OSC_OFF 0x80        /* part of 'sec' member *//* Masks for various portions of the time/date... */#define YEAR10_MASK     0xf0#define MONTH10_MASK    0x10#define DATE10_MASK     0x30#define DAY10_MASK      0x00#define HOUR10_MASK     0x30#define MINUTE10_MASK   0x70#define SECOND10_MASK   0x70#define CENTURY10_MASK  0x30#define YEAR_MASK       0x0f    /* Year is 0-99 */#define MONTH_MASK      0x0f    /* Month is 1-12 */#define DATE_MASK       0x0f    /* Date is 1-31 */#define DAY_MASK        0x07    /* Day is 1-7 */#define HOUR_MASK       0x0f    /* Hour is 0-23 */#define MINUTE_MASK     0x0f    /* Minutes is 0-59 */#define SECOND_MASK     0x0f    /* Seconds is 0-59 */#define CENTURY_MASK    0x0f    /* Century is 0-39 */struct dsdate {    uchar cent;     /* B7=W, B6=R, B5-4=10cent, B3-0=cent (00-39) */    uchar sec;      /* B7=OSC; B6-4=10secs; B3-0=sec (0-59) */    uchar min;      /* B6-4=10mins; B3-0=min (0-59) */    uchar hour;     /* B4-5=10hour; B3-0=hour (0-23) */    uchar wday;     /* B7=BF, B6=FT B2-0=day (1-7) */    uchar mday;     /* B4-5=10date; B3-0=date (1-31) */    uchar month;    /* B4=10mo; B3-0=month (1-12) */    uchar year;     /* MS-nibble=10Year; LS-nibble=year (0-99) */};#define DS1743REGS      ((struct dsdate *)DATEREGBASE)#define DS_century      (DS1743REGS->cent)#define DS_second       (DS1743REGS->sec)#define DS_minute       (DS1743REGS->min)#define DS_hour         (DS1743REGS->hour)#define DS_wday         (DS1743REGS->wday)#define DS_mday         (DS1743REGS->mday)#define DS_month        (DS1743REGS->month)#define DS_year         (DS1743REGS->year)#define SECONDS_IN_DAY  86400static charDaysInMonth[] = {    31, 28, 31, 30, 31, 30,     /* Jan, Feb, Mar, Apr, May, Jun */    31, 31, 30, 31, 30, 31      /* Jul, Aug, Sep, Oct, Nov, Dec */};/* rangecheck():    Return 0 if value is outside the range of high and low; else 1.*/static intrangecheck(int value, char *name, int low, int high){    if ((value < low) || (value > high)) {        printf("%s outside valid range of %d - %d\n",            name,low,high);        return(0);    }    return(1);}/* to_dsdatefmt(): * Take an incoming integer and convert it to the dallas time date * format using a 10-multiplier for the upper nibble. */static unsigned charto_dsdatefmt(int value){    int tens;    tens = 0;    while (value >= 10) {        tens++;        value -= 10;    }    return((tens << 4) | value);}static intfrom_dsdatefmt(unsigned char value, unsigned char mask10){    int newvalue;        newvalue = value & 0x0f;    newvalue += 10 * ((value & mask10) >> 4);    return(newvalue);}static voidshowDate(void){    int day, date, month, year, hour, minute, second, century;    DS_century |= READ; /* Set READ bit */    century = from_dsdatefmt(DS_century,CENTURY10_MASK);    second = from_dsdatefmt(DS_second,SECOND10_MASK);    minute = from_dsdatefmt(DS_minute,MINUTE10_MASK);    hour = from_dsdatefmt(DS_hour,HOUR10_MASK);    day = from_dsdatefmt(DS_wday,DAY10_MASK);    date = from_dsdatefmt(DS_mday,DATE10_MASK);    month = from_dsdatefmt(DS_month,MONTH10_MASK);    year = (((DS_year & 0xf0) >> 4) * 10) + (DS_year & 0x0f);    DS_century &= ~READ;    /* Clear READ bit */    printf("%02d/%02d/%02d%02d @ %02d:%02d:%02d\n",        month,date,century,year,hour,minute,second);}#if INCLUDE_TFSstatic intYearIsLeap(int year){    if (year % 4)       /* if year not divisible by 4... */        return(0);      /* it's not leap */    if (year < 1582)    /* all years divisible by 4 were */        return(1);      /* leap prior to 1582            */    if (year % 100)     /* if year divisible by 4, */        return(1);      /* but not by 100, it's leap */    if (year % 400)     /* if year divisible by 100, */        return(0);      /* but not by 400, it's not leap */    else        return(1);      /* if divisible by 400, it's leap */}/* GetAtime(): *  Build a string based on the incoming long value as described in  *  GetLtime()... *  Used by TFS to keep track of file time. */static char *GetAtime(long tval, char *buf, int bsize){    int year;       /* Actual year */    int doy;        /* Day of year */    int sid;        /* Seconds in day */    int leapyear;   /* Set if year is leap */    int month, hour, minute;    if ((bsize < 18)  || (tval == TIME_UNDEFINED)) {        *buf = 0;        return(buf);    }    /* Break down the basic bitfields: */    year = 2000 + ((tval >> 26) & 0x3f);    leapyear = YearIsLeap(year);    doy = ((tval >> 17) & 0x1ff);    sid = tval & 0x1ffff;    /* Now build the date from the bit fields: */    hour = sid / 3600;    sid -= (hour*3600);    minute = sid/60;    sid -= (minute*60);    month = 0;    while(doy > DaysInMonth[month]) {        doy -= DaysInMonth[month];         if ((month == 1) && (leapyear))            doy--;        month++;    }    sprintf(buf,"%02d/%02d/%02d@%02d:%02d:%02d",        month+1,doy,year,hour,minute,sid);    return(buf);}/* GetLtime(): *  Build a long with the following format.... *   *  B31-26      year since 2000     (0-127 yep, this breaks in 2128) *  B25-17      day of year         (1-365) *  B16-0       seconds in day      (0-86400) * *  Used by TFS to keep track of file time. */static longGetLtime(void){    long    tval;    int     year, month, mday, seconds, doy, leapyear;    DS_century |= READ; /* Set READ bit */    year = from_dsdatefmt(DS_year,YEAR10_MASK);         /* 00=2000 */    month = from_dsdatefmt(DS_month,MONTH10_MASK)-1;        /* 0-11 */    mday = from_dsdatefmt(DS_mday,DATE10_MASK);         /* 1-31 */    leapyear = YearIsLeap(year+2000);    if ((month > 11) || (month < 0) || (mday < 1) || (mday > 31))        return(TIME_UNDEFINED);    /* Determine current day of year... */    doy = mday;    while(month > 0) {        doy += DaysInMonth[month-1];        if ((month == 1) && leapyear)            doy++;        month--;    }    /* Determine current second of day... */    seconds = (from_dsdatefmt(DS_hour,HOUR10_MASK) * 3600);    seconds += (from_dsdatefmt(DS_minute,MINUTE10_MASK) * 60);    seconds += from_dsdatefmt(DS_second,SECOND10_MASK);    DS_century &= ~READ;    /* Clear READ bit */    tval = (((year & 0x3f) << 26) |            ((doy & 0x1ff) << 17) |            (seconds & 0x1ffff));    return(tval);}/* tfsTimeEnable(): *  Hook the file timestamping in TFS to the DS1743 device... */voidtfsTimeEnable(void){    tfsctrl(TFS_TIMEFUNCS,(long)GetLtime,(long)GetAtime);}#endifchar *DateHelp[] = {    "Display (mm/dd/yyyy@hh:mm:ss) or modify time and date.",    "[{day date month year hour min sec}]",    "Where...",    " day:   1-7 (sun=1)",    " date:  1-31",    " month: 1-12",     " year:  0-3899",     " hour:  0-23",     " min:   0-59",     " sec:   0-59",     "Note: 'date off' disables the oscillator",    0};intDate(int argc,char *argv[]){    int day, date, month, year, hour, minute, second, century, rngchk;    if ((DS_wday & BF) == 0)        printf("Warning: battery dead.\n");    if (argc == 1) {        if (DS_second & OSC_OFF)            printf("Warning: oscillator disabled.\n");        showDate();        return(CMD_SUCCESS);    }    else if ((argc == 2) && !strcmp(argv[1],"off")) {        DS_century |= WRITE;            /* Disable the oscillator */        DS_second = OSC_OFF;            /* to save battery life. */        DS_century &= ~WRITE;        return(CMD_SUCCESS);    }    else if (argc != 8)        return(CMD_PARAM_ERROR);    day = atoi(argv[1]);    date = atoi(argv[2]);    month = atoi(argv[3]);    year = atoi(argv[4]);    hour = atoi(argv[5]);    minute = atoi(argv[6]);    second = atoi(argv[7]);    rngchk = 0;    rngchk += rangecheck(day,"day",1,7);    rngchk += rangecheck(date,"date",1,31);    rngchk += rangecheck(month,"month",1,12);    rngchk += rangecheck(year,"year",0,3899);    rngchk += rangecheck(hour,"hour",0,23);    rngchk += rangecheck(minute,"minute",0,59);    rngchk += rangecheck(second,"second",0,59);    if (rngchk != 7)        return(CMD_PARAM_ERROR);        DS_century = WRITE;     /* Set WRITE bit */    DS_second = to_dsdatefmt(second) & ~OSC_OFF;    DS_minute = to_dsdatefmt(minute);    DS_hour = to_dsdatefmt(hour);    DS_wday = day;    DS_mday = to_dsdatefmt(date);    DS_month = to_dsdatefmt(month);    century = year / 100;    year = year % 100;    DS_year = to_dsdatefmt(year);    DS_century = (to_dsdatefmt(century)&(CENTURY_MASK|CENTURY10_MASK))|WRITE;    DS_century &= ~WRITE;       /* Clear WRITE bit */    return(CMD_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -