PDA

View Full Version : SD card file date stamp



Alexey
- 12th July 2012, 04:52
Hello All,

Could someone explain please how to use correctly SDFS.PBP include file in regards of correct handling file date. Everything seems to be working for me except of that when I create a file or open one for write, the date assigned to file (as I see it when then open the SD card on PC) is always 1992 instead of 2012, so I have to actually assign the value 12+20 in order to get 2012 when I then open card on Windows computer. The year is being read from RTCC which keeps two digits. I tried to set RTCC to 2020, 2039 year, etc. and if I add 20 before assigning this to the file date, everything seems to be working ok but I am not comfortable with this because I do not know why this happens

This is how I read RTCC:

READ_RTC:
I2CREAD RTCC_SDA, RTCC_SCL, RTC, SEC_REG, [sec,mins,hr,day,date,mon,yr]

...
YR_T = yr & %11110000
YR_T = YR_T>>4
YR_O = yr & %1111
YR_O = YR_O+10*YR_T 'here we must have 12 for this year
...

Than I record in file:

Gosub FSinit ' INIT card

ARRAYWRITE FAT_Filename, ["LOG TXT"]
' Set file time to CURRENT TIME and date
FAT_seconds = 0
FAT_minutes = MIN_O
FAT_hours = HR_O
FAT_day = DATE_O
FAT_month = MON_O
FAT_year = YR_O + 20 'HERE I HAVE TO ADD 20. NOT SURE WHY!

' Open a file for write
FAT_mode = "a" ' Append mode

Gosub FSfopen ' Open file pointed to by Byte array FAT_FileName

' Write to file
This way
' ARRAYWRITE FAT_src, [HEX2 DATE,"-", HEX2 MON,"-",HEX2 YR, ",", _
Or this way, no difference
ARRAYWRITE FAT_src, [HEX2 DATE,"-", HEX2 MON,"-",dec2 YR_o, ",", _
HEX2 HR, ":", HEX2 MINS,","]
FAT_count = 15
Gosub FSfwrite
...

Maybe zero year in FAT is 1980? same value appears as 1992 in file change date and as 12 in the record inside the file so it has to be incremented by 20 to become 2012 in the file time stamp

Please advise
Thank you very much!

mackrackit
- 12th July 2012, 11:16
You can look this test code over. I have the serial output for debugging.


'FL PIC18F4550
'TEST RTC TO SD CARD
'18F4550
'02/28/09
'
DEFINE OSC 48
@ __CONFIG _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
@ __CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _ICPRT_OFF_4L &_XINST_OFF_4L



' Alias PIC pins and registers for SD/MMC card
SD_WE Var PORTA.4 ' SD card write protect
SD_WE_TRIS Var TRISA.4 ' SD card write protect direction
'SDI Var PORTB.0 ' SPI data in SD #7
'SDI_TRIS Var TRISB.0 ' SPI data in direction
SDI Var PORTB.2 ' SPI data in SD #7
SDI_TRIS Var TRISB.2 ' SPI data in direction
SCL Var PORTB.1 ' SPI clock SD #5
SCL_TRIS Var TRISB.1 ' SPI clock direction
SD_CS Var PORTB.3 ' SD card chip select SD #1
SD_CS_TRIS Var TRISB.3 ' SD card chip select direction
SD_CD Var PORTB.4 ' SD card detect
SD_CD_TRIS Var TRISB.4 ' SD card detect direction
SDO Var PORTC.7 ' SPI data out SD #2
SDO_TRIS Var TRISC.7 ' SPI data out direction

ON INTERRUPT GOTO T_INT
INTCON = %10010000
CNT VAR WORD
CNT = 0
BOOT:
CLEAR

XCNT VAR LONG
OCNT VAR BYTE
OCNT = 0
TCNT VAR BYTE
TCNT = 0
Z VAR LONG
Z = 0


GPS VAR BYTE[53]
RTC_STR VAR BYTE[25]
N1 VAR BYTE[4]
N2 VAR BYTE[3]

TEMPERATURE VAR BYTE
T_ONES VAR BYTE
T_TENS VAR BYTE
TEMPERATURE = 99
T_TENS = TEMPERATURE/10
T_ONES = TEMPERATURE-(T_TENS*10)

'RTC DEFINES
DS_SCL VAR PORTD.1
DS_SDA VAR PORTD.0
RTC CON %11010000
'Setting the RTC so we can get out 1Hz tick output
'-------------------------------------------------
' -------------- RTC definitions -----------------
SecReg CON $00 ' seconds address (00 - 59) ' MSB of SecReg must be set to a 0 to enable RTC
ContReg CON $0E ' control register
cntrl CON %00000000 ' sets the SQW/OUT to 1Hz pulse, logic level low
' The variable below holds the values entered:
' entered by the user
sec VAR BYTE ' seconds
MINs VAR BYTE ' minutes
hr VAR BYTE ' hours
day VAR BYTE ' day
date VAR BYTE ' date
mon VAR BYTE ' month
yr VAR BYTE ' year

SEC_O VAR BYTE
SEC_T VAR BYTE
MIN_O VAR BYTE
MIN_T VAR BYTE
HR_O VAR BYTE
HR_T VAR BYTE

'ALARM VARIABLES
A_MINs VAR BYTE ' minutes
A_hr VAR BYTE ' hours
I2CWrite DS_SDA, DS_SCL, RTC, ContReg, [cntrl]
' Include the SD/MMC subroutines
Include "SDFS.BAS"
SDC_UseHardSPI = FALSE ' Use hardware SSP port for SPI.

ADCON1 = 15 ' All I/O pins digital
TRISD =%00000000

PAUSE 1000
Serout2 PORTC.6, 16572, [ "MACKRACKIT ", $d, $a]
Serout2 PORTC.6, 16572, [ "RTC ", $d, $a]
Pause 1000

'###GOSUB SET_RTC

HIGH PORTD.7
'###########################################
CHECK:
IF CNT = 600 THEN
CNT = 0
GOSUB RUN
ENDIF
GOTO CHECK

RUN:
TOGGLE PORTD.7
I2CRead DS_SDA, DS_SCL, RTC, SecReg, [sec,MINs,hr,day,date,mon,yr]
pause 100
Serout2 PORTC.6, 16572, [ "RUN ", $d, $a]
Serout2 PORTC.6, 16572, [ "TIME ", HEX2 hr, ":", HEX2 MINs, ":", HEX2 sec,$d, $a]
Serout2 PORTC.6, 16572, [ "DATE ", HEX2 mon,"-",HEX2 date,"-",HEX2 yr,$d, $a]
Serout2 PORTC.6, 16572, [ "INT COUNT ", DEC CNT,$d, $a]

PAUSE 1000

SEC_T = sec & $70
SEC_T = SEC_T>>4
Serout2 PORTC.6, 16572,["SEC_T ",DEC SEC_T, $d, $a]
SEC_O = sec & $0F
Serout2 PORTC.6, 16572,["SEC_O ",DEC SEC_O, $d, $a]

MIN_T = MINs & $70
MIN_T = MIN_T>>4
Serout2 PORTC.6, 16572,["MIN_T ",DEC MIN_T, $d, $a]
MIN_O = MINs & $0F
Serout2 PORTC.6, 16572,["MIN_O ",DEC MIN_O, $d, $a]

HR_T = hr & $70
HR_T = HR_T>>4
Serout2 PORTC.6, 16572,["HR_T ",DEC HR_T, $d, $a]
HR_O = hr & $0F
Serout2 PORTC.6, 16572,["HR_O ",DEC HR_O, $d, $a]

'GOTO SD_MAIN

'GOTO RUN
'###############################################

SD_MAIN:
TOGGLE PORTD.7
' PAUSE 250
GOSUB SDINIT
GOSUB SDFILENAME
GOSUB SDOPEN_W
GOSUB SD_WRITE
GOSUB SDCLOSE
' GOSUB SD_READ

'GOTO SD_MAIN

'GOTO RUN
RETURN
'################################################# #############
SDINIT:
' FSInit initializes the card and reads all the preliminary information from it
Gosub FSInit
Serout2 PORTC.6, 16572, ["Init: ", Dec FAT_error, " ", Dec SDC_status, " ", Dec SDC_response, $d, $a]
IF (FAT_error = 6) THEN SD_MAIN
If (FAT_error != 0) Then Stop

' Display card directory
Gosub FINDfirst ' Find first file on card
While (FAT_error = 0)
Serout2 PORTC.6,16572, [Str FAT_FileName\11, $d, $a]
Gosub FINDnext ' Find next file on card
Wend
RETURN
'################################################# ###############
SDFILENAME:

' This section defines a specific short (8.3) filename
' Note that spaces are use in empty elements and must be upper case for Windows
FAT_FileName[0] = "G"
FAT_FileName[1] = "P"
FAT_FileName[2] = "S"
FAT_FileName[3] = " "
FAT_FileName[4] = " "
FAT_FileName[5] = " "
FAT_FileName[6] = $30+TCNT
FAT_FileName[7] = $30+OCNT
FAT_FileName[8] = "T"
FAT_FileName[9] = "X"
FAT_FileName[10] = "T"

' Set file time to 8:30:10 and date to 1/1/2008
FAT_seconds = sec
FAT_minutes = MINs
FAT_hours = hr
FAT_day = date
FAT_month = mon
FAT_year = 20+yr
RETURN
'################################################# ###########
SDOPEN_W:
' Open a file for write
FAT_mode = "A" ' Write mode
Gosub FSfopen ' Open file pointed to by Byte array FAT_FileName

Serout2 PORTC.6, 16572, ["Open for write Error: ", Dec FAT_error, $d, $a]

Serout2 PORTC.6, 16572, [ "FILE NAME ", STR FAT_FileName\11, $d, $a]
Serout2 PORTC.6, 16572, [ "DISK_fat ", Dec DISK_fat, $d, $a]
Serout2 PORTC.6, 16572, [ "DISK_buffer ", Dec DISK_buffer, $d, $a]
Serout2 PORTC.6, 16572, [ "SDC_sector_addr ", Dec SDC_sector_addr, $d, $a]
Serout2 PORTC.6, 16572, [ "FAT_ccls ", Dec FAT_ccls, $d, $a]
Serout2 PORTC.6, 16572, [ "LAST_CLUSTER ", Dec LAST_CLUSTER, $d, $a]
Serout2 PORTC.6, 16572, [ "FAT_c ", Dec FAT_c, $d, $a]
Serout2 PORTC.6, 16572, [ "DISK_maxcls: ", Dec DISK_maxcls, $d, $a]

'IF (FAT_error = 10) THEN Stop

IF (FAT_error = 10) THEN XNAME
If (FAT_error != 0) Then BOOT 'SD_MAIN
RETURN
'################################################# ##############
SD_WRITE:
' Write to file
Z = 0
'FOR XCNT = 1 TO 33
FAT_src[0] =$30+HR_T
FAT_src[1] =$30+HR_O
FAT_src[2] = ":"
FAT_src[3] = $30+MIN_T
FAT_src[4] = $30+MIN_O
FAT_src[5] = ":"
FAT_src[6] = $30+SEC_T
FAT_src[7] = $30+SEC_O
FAT_src[8] = " "
FAT_src[9] = " "
FAT_src[10] = " "
FAT_src[11] = " "
FAT_src[12] = " "
FAT_src[13] = " "
FAT_src[14] = $d
FAT_src[15] = $a


FAT_count = 16
Gosub FSfwrite
Z = Z + 1
Serout2 PORTC.6, 16572, [ "ROLL OVER AT 100000 ", Dec Z," FCNT ",DEC TCNT,DEC OCNT, $d, $a]

'NEXT XCNT
Serout2 PORTC.6, 16572, [ "Write ",Dec FAT_error, $d, $a]

IF (FAT_error = 10) THEN Stop
If (FAT_error != 0) Then STOP
'GOSUB SDCLOSE
'Serout2 PORTC.6, 16572, [ "DONE ", $d, $a]
'STOP
RETURN
'################################################# ##############
XNAME:

'IF O = 10 THEN
'O = 1
'T = T + 1

OCNT = OCNT + 1
IF OCNT = 10 THEN 'TCNT = TCNT + 1 AND OCNT = 0
OCNT = 0
TCNT = TCNT + 1
ENDIF
IF TCNT = 10 THEN STOP
GOTO SD_MAIN
'################################################# #########
SDCLOSE:
' Close file
Gosub FSfclose
Serout2 PORTC.6, 16572, [ "Close ", Dec FAT_error, $d, $a]
If (FAT_error != 0) Then Stop

RETURN
'################################################# ###########
SD_READ:
' Open a file for read
FAT_mode = "r" ' Read mode
Gosub FSfopen ' Open file pointed to by Byte array FAT_FileName
Serout2 PORTC.6, 16572, ["Open: ", Dec FAT_error, $d, $a]
If (FAT_error != 0) Then Stop

' Read and display the whole file
FAT_count = 1 ' Read 1 byte to buffer at a time
Gosub FSfread
While (FAT_error = 0)
Serout2 PORTC.6, 16572, [FAT_dest[0]]
FAT_count = 1 ' Read 1 byte to buffer at a time
Gosub FSfread
Wend
Serout2 PORTC.6, 16572, [$d, $a, "Read: ", Dec FAT_error, $d, $a]
RETURN
'#################################################
SET_RTC:
yr = $10
mon = $02
date = $14
sec = $00
mins = $44
hr = $01
I2CWrite DS_SDA, DS_SCL, RTC, SecReg, [sec,mins,hr,day,date,mon,yr]
RETURN
DISABLE
T_INT:
CNT = CNT + 1
INTCON.1 = 0
RESUME
ENABLE

Alexey
- 18th July 2012, 05:12
Thank you very much for sharing the code, Mackrackit, I see you do the same: FAT_year = 20+yr