This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP-EXP430FR5994: Out-Of-Box sample code setting wrong date in file

Part Number: MSP-EXP430FR5994
Other Parts Discussed in Thread: MSP430FR5994

I have attached a camera to the MSP430FR5994 launchpad and use the Out-Of-Box sample code to store a photos on the launchpad's SDCard. I successfully store images and create log files.  But the hour field in file time/date stamps are wrong - they are 1 hour less than specified value (hour 5 becomes 4, hour 6 becomes 5).

My code has a default time-stamp calendar and allows a user to change it ("calendar" is a "Calendar struct" which hold the fields of the time-stamp. The debugger shows the correct value in the calendar fields. So the problem is downstream (I think). The mmc.c translation unit (HAL library)  has get_fattime() function which is called by FATFS to pack the calendar into a DWORD (per the DOS format). This function had a bug which I corrected (the original failed to shift the "seconds" field to the right 1 bit position). But other than this, the FATFS system is unchanged.

 Can anyone running the sample code on the msp430FR5994 launchpad confirm that files are created at the expected times? If this problem is unique to my porting then any guidance is most appreciated.

Jim

Below are five items:

  1. The first item is the modified get_fattime() code snippet.
  2. the second image shows the default calendar settings in the code window. The terminal window (lower right) shows the user supplied timestamp. Both use hour 05.
  3. the third image shows the sdcard's directory (viewed using a windows 10 machine). Here the date hour is 04. I expected 05.
  4. the fourth image shows the debugger window. it shows that calendar has the correct date values (hour 5).
  5. the fifth image shows a debugger window where the execution is breakpointed in the mkdir. The "tim" variable receives mmc's get_fattime() which should have the packed timestamp from calendar. The contents of the DWORD tim are 0x13156896 (HR:13, Min:04. sec:22). Certainly not what I expected (perhaps calendar holds the creation date of the directory but the directory was created around 5 as well so I don't understand this

thank you

jim

DWORD get_fattime(void)
{
	DWORD tmr;

	/* Pack date and time into a DWORD variable */
	Calendar curTime = sdInterface->sdGetRTCTime();

	tmr = ((DWORD)(curTime.Year-1980)<<25)
			| ((DWORD)(curTime.Month) << 21)
			| ((DWORD)(curTime.DayOfMonth) << 16)
			| (curTime.Hours << 11)
			| (curTime.Minutes << 5)
			| (curTime.Seconds >> 1); //modified to truncate into two second intervals - jn

	return tmr;
}

  • Hi James,

    As mentioned in the other thread, I'll dig into this and respond shortly.

  • thank you  Mr. Lehman

    I should mention that I am using the RTC in binary format (not bcd as shown in the original out-of-box code below).

    I ported the code to interface to a terminal instead of the GUI. this is where I found that the  BCD format scrambles the epoch time in SDCardLog.c. and switched to binary which gave the correct epoch time.

    But I am wondering if the FATFS is expecting the RTC registers in BCD format instead of binary.  However, get_fattime() expects binary and I didn't find a BCD to binary conversion (either by the HW or by a SW algorithm) so I assumed fatfs wants binary. If so, why did the original code author (E.Chen) use BCD? Was it for the GUI interface?

       

    /*
     * Real Time Clock Initialization
     */
    void Init_RTC()
    {
        //Setup Current Time for Calendar
        calendar.Seconds    = 0x55;
        calendar.Minutes    = 0x30;
        calendar.Hours      = 0x04;
        calendar.DayOfWeek  = 0x01;
        calendar.DayOfMonth = 0x30;
        calendar.Month      = 0x04;
        calendar.Year       = 0x2014;
    
        // Initialize RTC with the specified Calendar above
        RTC_C_initCalendar(RTC_C_BASE,
                           &calendar,
                           RTC_C_FORMAT_BCD);
    
        RTC_C_setCalendarEvent(RTC_C_BASE,
        		               RTC_C_CALENDAREVENT_MINUTECHANGE
        		               );
    
        RTC_C_clearInterrupt(RTC_C_BASE,
                             RTC_C_TIME_EVENT_INTERRUPT
                             );
    
        RTC_C_enableInterrupt(RTC_C_BASE,
                              RTC_C_TIME_EVENT_INTERRUPT
                              );
    
        //Start RTC Clock
        RTC_C_startClock(RTC_C_BASE);
    }
    

  • One more observation in my debug efforts..

    In the HAL_SDCard.c module the code expects the RTC to be in binary format. The inconsistent use of the RTC format (BCD in Init_RTC() and Binary in Sdcard_setRTC()  ) seems a bit unusual. My current thinking is that somewhere downstream there is a conversion between BCD and binary and that perhaps my code which started as binary gets scrambled. I am currently looking at f_open() and f_sync() to see where they pull the timestamp. 

    void SDCard_setRTCTime(Calendar *curTime)
    {
        //Initialize Calendar Mode of RTC
        RTC_C_initCalendar(RTC_C_BASE,
        		curTime,
    			RTC_C_FORMAT_BINARY);
    
        //Start RTC Clock
        RTC_C_startClock(RTC_C_BASE);
    }

  • some additional information that might be helpful.

    I put a code break at get_RTCTime() in the HAL layer. this is where fatfs fetches the date-time stamp when creating a directory or opening a file. The RTC is not running at the point. The state of the RTC registers are the expected default values set early in main(). Because the RTC is NOT running there should be no synchronization issues reading the time registers. Stopping the program and plugging in the sdcard into windows 10 shows empty date-time fields. The elm-chaN fatfs website that illegal date-time stamps are either ignored or create unpredictable behavior. In this case, the fields are ignored. So fatfs thinks the RTC registers hold illegal values. My first thought was that maybe fatfs wants something other than binary values. I can't imagine what since get_RTCTime() returns a calendar to get_fattime() which seems to expect binary values which it packs the date-time stamp into the 32b DOS format. 

    looking at get_fattime() in mmc.c, it casts the uint8_t to DWORD for the most high order bytes (year, month, day) but does not cast the low order bytes which remain in uint8_t. I wouldn't think this is a problem but I am grasping at straws at this point. Somehow the date-timestamp is corrupted going into fatfs and this appears where it might happen.

    DWORD get_fattime(void)
    {
    	DWORD tmr;
    
    	/* Pack date and time into a DWORD variable */
    	Calendar curTime = sdInterface->sdGetRTCTime();
    
    	tmr = ((DWORD)(curTime.Year-1980)<<25)
    			| ((DWORD)(curTime.Month) << 21)
    			| ((DWORD)(curTime.DayOfMonth) << 16)
    			| (curTime.Hours << 11)
    			| (curTime.Minutes << 5)
    			| (curTime.Seconds >> 1); //modified to truncate into two second intervals - jn
    
    	return tmr;
    }

    I changed it to:

    DWORD get_fattime(void)
    {
    	DWORD tmr;
    
    	/* Pack date and time into a DWORD variable */
    	Calendar curTime = sdInterface->sdGetRTCTime();
    
    	tmr = ((DWORD)(curTime.Year-1980)<<25)
    			| ((DWORD)(curTime.Month) << 21)
    			| ((DWORD)(curTime.DayOfMonth) << 16)
    			| ((DWORD)(curTime.Hours) << 11)
    			| ((DWORD)(curTime.Minutes) << 5)
    			| ((DWORD)(curTime.Seconds) >> 1); //modified to truncate into two second intervals - jn
    
    	return tmr;
    }

    I then reran my tests. I reran an earlier test which failed to put date-time stamps on my files and directories. This time I have date-time stamps. I need to do more testing.

  • I ran a second test with different date-time entries with mostly good results. All files and directories now have date-time stamps. However the hours are 1 less than specified (for example I specified 22 hours military time and get 9 PM in the date-time stamp field. I need to find where military time is converted to AM/PM time.  

    The hours should now be correctly packed in tmr. I suspect f_sync does the unpacking and will look there next. 

  • some people I talked think the code should have worked and this is a compiler issue. 

  • I realized that the fatfs uses the dos date-time bitmap to store date and time. How that bitmap is interpreted is up to the OS (in other words, AM and PM are not part of FatFS, it is part of how Windows display files and directories). The wrong hour I was getting was a Windows 10 issue. I changed my setting to show 24hr time and the timestamps are correct. 

    I believe that the original code should have worked. It was developed on an earlier or different compiler which compiled the code correctly. The work around is to explicitly add the DWORD to each of the uint8_T entities (Hours, Minutes, Seconds). Maybe someone at TI can look into this and file a compiler bug report. 

    And maybe someone at TI will add the shift right one bit to the seconds code in the out-of-box code - that was a real code bug. 

**Attention** This is a public forum