Shop OBEX P1 Docs P2 Docs Learn Events
Learning the RTC — Parallax Forums

Learning the RTC

I am trying to find the handle on the RTC functions before firing up my new DS3231 and I have a couple of questions.

From Extend5v4.FTH:
--- STAMP@ returns a 32-bit millisecond time + day of month in top 5-bits
pub STAMP@ ( --- dhmsc ) time @ day 1+ C@ 27 << + ;

When I call STAMP@ it returns milliseconds but no DOM.
Example:
... .DT --> Mon, 31 Jan 2001 00:16:47 UTC ok
... STAMP@ . --> 1021375 ok

... that is the number of milliseconds in the time but nothing for the 31st day of the month.

What am I missing?

Comments

  • Here is another:

    --- select and set RTC device
    pub SETRTC ( $opt.addr -- ) W>B ' sec# C! ' rtc# C! ;

    The parameter $opt.addr -> does that indicate that the $opt.addr is a string. If the designation were 'addr' I would take it to mean the I2C address of the RTC but I am confused. Furthermore the Tachyon Extend source specifies $D0 as the address for DS3231. Other sources say $68. If I knew how to make this word work I would just try both.

    He'p!
  • Well okay here we go again. Just after asking a question -> find the answer.

    Just 7 lines down in the code "DS3231 $D0 SETRTC

  • artkennedyartkennedy Posts: 174
    edited 2020-05-07 02:47
    Date arithmetic anyone? Don't know if this has been done before in Forth or Tachyon. If so I have flung a lot of sweat reinventing the wheel. I thought I would like to have functions DATE+ and DDAYS like the ones on my Hp-48's. I thought it would be simple. Big laugh. Anyway it passes my test. If anyone is interested you are welcome to use it but you should test it first. It has passed my tests but I might have missed something. If you find something to improve I would like to know about it.
    --- Version 0.4
    
    FORGET daymo
    TABLE daymo
      0 || 31 || 59 || 90 || 120 || 151 || 181 || 212 || 243 || 273 || 304 || 334 || 365 ||
    
    : DOM1           ( mm -- dom1 )  --- dom1 - 1st day of month
          1- daymo SWAP 2 * + W@  --- fetch first day of month ( base 0 )
    ;
    
    : SYSDAY      ( yymmdd -- sysday ) --- 20010101 subtracted from yymmdd,
                                         ---   sysday = number of days since 20010101 (Jan 01, 2001) base 0.
        HMS -ROT        --- ( yymmdd -- yy dd mm )
        3RD 4 MOD       --- (  -- yy dd mm lyf )  lyf = 1 if leap year
        OVER DOM1 1-    --- (  -- yy dd mm lyf Zdom ) dom1 - 1 = Zdom, Zeroth day of month
        ROT 2 >         --- (  -- yy dd lyf Zdom ldf ) ldf = 1 if March or later
        ROT NOT         --- (  -- yy dd Zdom ldf lyf )
        AND NOT         --- (  -- yy dd Zdom lda ) lda = leap day addition if any
        + + 1+          --- (  -- yy doy ) doy = day of year (base 0) with leap adjustment, 1+ restores Zdom offset
        SWAP 1-         --- (  -- doy pyy )     pyy = prev years
        DUP 4 /         --- (  -- doy pyy pld ) pld = how many prev leap days
        SWAP 365 * + +  --- (  -- sysday ) # of prev regular days - sum, sysday (see above)
    ;
    
    : DOY1  ( yy --- doy1 )  --- yy = year, doy1 = first day thereof , totally confirmed.
          1- DUP 4 /            --- num of prev leap days, calculation is done with ordinal of previous year
          SWAP 365 * +          --- add leap days --> sysday of first doy
    ;
    
    : YRDOY   ( sysday -- yy doy ) --- true year and doy ( includes leap day )
        DUP 365 / 1+ DUP DOY1      --- guess the year and check it out
                                   ---       ( sysday 365 / returns the year before the target...therefore 1+ )
        3RD SWAP -                 --- sysday - doy1
        DUP 0< IF                  --- IF negative result ( means year is +1 )
          DROP                     ---   drop result
          1- DUP DOY1              ---   decrement year and try again
          ROT SWAP -               ---   sysday - doy1 --> good this time
        ELSE                       --- ELSE
          ROT DROP                 ---   drop sysday
        THEN                       --- THEN
    ;
    
    : DAYMO       ( doy -- mm dd )   --- derive month and day of month from day of year
        daymo 22 + FROM -2 BY 12     --- search backward through daymo for 1dom equal to or less than doy
        FOR
          DUP
          I W@
          => IF I LEAVE THEN         --- found it!
        NEXT
        DUP daymo - 2/ 1+            --- extract mm from search address
        -ROT W@ - 1+                 --- subtract doy of first day of month from target doy
    ;
    
    : DAY>DATE        ( sysday -- yymmdd )       --- sysday to yymmdd
        YRDOY                ( sysday -- yy doy )
        OVER 4 MOD 0 > NOT   ( -- yy doy lyf )      --- leap year?
        OVER 59 >            ( -- yy doy lyf ldf )  --- after leap day if any?
        AND +                ( -- yy doy )          --- combine flags and use result to increment doy or not
        DAYMO                ( -- yy mm dd )        ---
        4TH 59 =             ( -- yy mm dd lyf )    ---
        4TH 4 MOD NOT AND    ( -- yy mm dd ldsf )   --- ldsf = ld substitution flag
        IF                   ( -- yy mm dd )        --- if ld sensed
          2DROP 2 29         ( -- yy mm' dd' )      ---   leap day substituted
        THEN                 ( -- )                     --- then
        SWAP 100 * +         ( -- yy mmdd )         --- compile yymmdd
        SWAP 10000 * +       ( -- yymmdd )
    ;
    
    : DOW   ( sysday -- dow )
             1+ 7 MOD
    ;
    
    : DATE+  ( yymmdd n -- yymmdd + n )
        SWAP SYSDAY
        + DAY>DATE
    ;
    
    : DDAYS  ( yymmdd yymmdd' -- ddays )  --- subtract yymmdd' from yymmdd --> days between two dates
           SYSDAY SWAP SYSDAY SWAP -
    ;
    
Sign In or Register to comment.