' ##################################################################################
'
' Read RTC PCF8583 Function and Write RTC PCF8583 Subroutine
'
' ##################################################################################
'
'(
This file contains subroutine to write date in time into PCF8583 RTC
and function to read date and time from PCF8583 RTC

User must
1. use Bascom version 2.0.7.6 or younger, which supports
   CONFIG SUBMODE = NEW

2. Specify CONFIG SUBMODE = NEW
3. $Include PCF8583.inc  -  include this file
4. Specify I2C bus with appropriate CONFIG statements. For example:

   Config Sda = Portd.7                                        ' mandatory, depending on shematic
   Config Scl = Portd.5

5. Define constans WRTC (write RTC) and RRTC (Read RTC)
   for addressing chip.

   For example:
   Const Wrtc = &HA0                                           ' mandatory, depending on address pin of RTC
   Const Rrtc = &HA1

6. For writing Date and Time to chip user must provide data in a string variable as follows:
   2 characters for day of month (01 - 31).
   2 characters for month (01 - 12)
   2 characters for yeas (00 - 99)
   blanc character
   2 characters for hour (00 - 23)
   2 characters for minute (00 - 59)
   blanc character
   2 characters for day of the week Su or Mo or Tu or We or Th or Fr or Sa
       If you will have this data in some other language than english,
       you are free to change coresponding Data statents in source of this program
       at label pcf8583dow

7. Call subroutine Wpcf8583sub with data

   For Example:

   Dim Wrkstr As String * 32
   Wrkstr = "210413 2013 Mo"

   Wpcf8583sub Wrkstr


7. For reading Date and Time from the chip
   Call Function Rpcf8583fun

   For Example:
   Wrkstr = Rpcf8583fun()

   and you get the data in same format as it was given before.


Here is an example of complete program:

#####################################################################################

Const Program = "RTC"
$regfile = "m644pdef.dat"
$crystal = 11059200
$baud = 19200
$hwstack = 384
$swstack = 128
$framesize = 128

Config Submode = New                                        ' must !
$include Pcf8583.inc                                        ' must !


Open "comb.4:9600,8,n,1" For Output As #2                   ' UART for monitoring

'                               I2C
'                           RTC PCF8583
'                           =============
Config Sda = Portd.7                                        ' mandatory, depending on shematic
Config Scl = Portd.5
Const Wrtc = &HA0                                           ' mandatory, depending on address pin of RTC
Const Rrtc = &HA1


'  Let us provide some date and time to be written in RTC
'  for example:  Monday,  2. April 2013  at 2013 Hours

Dim Wrkstr As String * 32
Wrkstr = "210413 2013 Mo"
Print #2 , Wrkstr


'  call write RTC subroutine and submit date and time:
Wpcf8583sub Wrkstr


Do
   ' call read RTC function and print result
   Print #2 , Rpcf8583fun()

   Wait 2

Loop
End
Close #2
#####################################################################################


')


' ###################################################################################
'
'   Wpcf8583sub Subroutine:
'
' ###################################################################################
Sub Wpcf8583sub(byref Dateandtime As String)

Local Minu As Byte
Local Hour As Byte
Local Datt As Byte                                          ' 2 bits for year
Local Mont As Byte                                          ' 3 bits for day of week
Local Year As Byte
Local I As Byte
Local Littlestring As String * 6


  '  ddmmyy hhmm pcf8583dow
  '  1.3.5..8.,,....
  '          10 13
  '  example:
  ' "020413 2223 Mo"  April 2nd 2013 at 2223 Hour

  Littlestring = Left(dateandtime , 2)
  Datt = Val(littlestring)
  Datt = Makebcd(datt)

  Littlestring = Mid(dateandtime , 3 , 2)
  Mont = Val(littlestring)
  Mont = Makebcd(mont)

  Littlestring = Mid(dateandtime , 5 , 2)
  Year = Val(littlestring)

  Littlestring = Mid(dateandtime , 8 , 2)
  Hour = Val(littlestring)
  Hour = Makebcd(hour)

  Littlestring = Mid(dateandtime , 10 , 2)
  Minu = Val(littlestring)
  Minu = Makebcd(minu)

  Littlestring = Mid(dateandtime , 13 , 2)
  For I = 6 To 0 Step -1
       Littlestring = Lookupstr(i , Pcf8583dow)
       If Littlestring = Mid(dateandtime , 13 , 2) Then Exit For
  Next
  Shift I , Left , 5
  Mont = Mont Or I

  I = Year Mod 4
  Shift I , Left , 6
  Datt = Datt Or I


         I2cstart                                           '
         I2cwbyte Wrtc                                      ' in zapišemo nazaj
         I2cwbyte 2                                         '
         I2cwbyte 0                                         ' seconds                                         '                           '
         I2cwbyte Minu                                      ' minutesI                                         '                           '
         I2cwbyte Hour                                      ' hour                                         '                           '
         I2cwbyte Datt                                      ' datu                          '
         I2cwbyte Mont                                      ' mese                          '
         I2cstop

         I2cstart                                           '
         I2cwbyte Wrtc                                      ' in zapišemo nazaj
         I2cwbyte 16                                        '
         I2cwbyte Year                                      '                           '
         I2cstop

End Sub

' ###################################################################################
'
'   Rpcf8583fun Function:
'
' ###################################################################################


Function Rpcf8583fun() As String
Local Minu As Byte
Local Hour As Byte
Local Datt As Byte                                          ' 2 left bits year
Local Mont As Byte                                          ' 3 left bits day of week
Local Year As Byte                                          ' in ram byte 16 from 00 to 255
Local I As Byte
Local J As Byte

    I2cstart
    I2cwbyte Wrtc
    I2cwbyte 2
    I2cstart
    I2cwbyte Rrtc
    I2crbyte Minu , Ack                                     ' ignore seconds
    I2crbyte Minu , Ack
    I2crbyte Hour , Ack
    I2crbyte Datt , Ack
    I2crbyte Mont , Ack
    I2crbyte Year , Ack                                     ' ignore some bytes
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Ack
    I2crbyte Year , Nack                                    ' read  year
    I2cstop

    J = Datt
    Shift J , Right , 6
    I = Year Mod 4
    If J <> I Then
         Incr Year
         I2cstart
         I2cwbyte Wrtc
         I2cwbyte 16
         I2cwbyte Year                                      '
         I2cstop
    End If

    I = Datt And &H3F
    Rpcf8583fun = Hex(i)
    I = Mont And &H1F
    Rpcf8583fun = Rpcf8583fun + Hex(i) + Str(year) + " "
    Rpcf8583fun = Rpcf8583fun + Hex(hour) + Hex(minu) + " "
    I = Mont
    Shift I , Right , 5
    Rpcf8583fun = Rpcf8583fun + Lookupstr(i , Pcf8583dow)

Pcf8583dow:
Data "Su"
Data "Mo"
Data "Tu"
Data "We"
Data "Th"
Data "Fr"
Data "Sa"

End Function