Skip to content

[STM32XX] Fix RTC minimum date #2127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 15, 2016
Merged

Conversation

svastm
Copy link
Contributor

@svastm svastm commented Jul 8, 2016

Problem

  • The MBED_16 fail on STM32F0 targets.
  • None of the ST targets are able to set_time(0) => year 1970 correctly.

Fix

STM32F0, STM32F3, STM32F4, STM32F7, STM32L0, STM32L1, STM32L4

They use a BCD format to store the date in the RTC. The year is store on 2 * 4 bits. Because the first year is reserved to see if the RTC is init, the supposed range is 01-99. The idea is to cover the standard range from 1970 to 2038 (limited by the 32 bits of time_t).

The fix move the RTC range to match the standard one. The idea is to keep the year 1970 and the leap years synchronized. By moving it 68 years forward from 1970, it become 1969-2067 which include 1970-2038. 68 is also a multiple of 4 so it let the leap year synchronized. Between 1904 and 2096 there is a leap year every 4 years.

STM32F1

They don't use a BCD format but a 32bit register for the seconds and a software structure to store dates. It should not be a problem to not use shifts.

Test

I used the following code to test the fix.

#include "mbed.h"
#include "test_env.h"

#if !DEVICE_RTC
  #error [NOT_SUPPORTED] RTC is not supported
#endif

int main() {
    MBED_HOSTTEST_TIMEOUT(20);
    MBED_HOSTTEST_SELECT(st_rtc_min);
    MBED_HOSTTEST_DESCRIPTION(st_rtc_min);
    MBED_HOSTTEST_START("ST_RTC_MIN");

    struct tm timeinfo;
    time_t seconds = 0;
    char buffer[32] = {0};
    bool result = true;

    // test the minimum date
    // Set time to 1 Jan 1970 00:00:00
    timeinfo.tm_mon  = 0;
    timeinfo.tm_mday = 1;
    timeinfo.tm_year = 70;
    timeinfo.tm_hour = 0;
    timeinfo.tm_min  = 0;
    timeinfo.tm_sec  = 0;
    timeinfo.tm_isdst  = -1;
    set_time(mktime(&timeinfo));

    // Print the time
    seconds = time(NULL);
    strftime(buffer, 32, "%Y-%m-%d %H:%M:%S %p", localtime(&seconds));
    printf("MBED: [%ld] [%s]\r\n", seconds, buffer);

    if (strcmp(buffer,"1970-01-01 00:00:00 AM") != 0) {
      result = false;
    }

    // test the leap years
    // Set time to 28 Feb 2032 23:59:59
    timeinfo.tm_mon  = 1;
    timeinfo.tm_mday = 28;
    timeinfo.tm_year = 132;
    timeinfo.tm_hour = 23;
    timeinfo.tm_min  = 59;
    timeinfo.tm_sec  = 59;
    timeinfo.tm_isdst  = -1;
    set_time(mktime(&timeinfo));
    wait(1.1);

    // Print the time
    seconds = time(NULL);
    strftime(buffer, 32, "%Y-%m-%d %H:%M:%S %p", localtime(&seconds));
    printf("MBED: [%ld] [%s]\r\n", seconds, buffer);

    if (strcmp(buffer, "2032-02-29 00:00:00 AM") != 0) {
      result = false;
    }

    // test the maximum date
    // IAR use to fail on this one because his year 2038 bug seems to 
    // happen the 6 Feb 2036
    // Set time to 19 Jan 2038 03:14:00
    timeinfo.tm_mon  = 0;
    timeinfo.tm_mday = 19;
    timeinfo.tm_year = 138;
    timeinfo.tm_hour = 3;
    timeinfo.tm_min  = 14;
    timeinfo.tm_sec  = 0;
    timeinfo.tm_isdst  = -1;
    set_time(mktime(&timeinfo));
    wait(1.1);

    // Print the time
    seconds = time(NULL);
    strftime(buffer, 32, "%Y-%m-%d %H:%M:%S %p", localtime(&seconds));
    printf("MBED: [%ld] [%s]\r\n", seconds, buffer);

    if (strcmp(buffer, "2038-01-19 03:14:01 AM") != 0) {
      result = false;
    }

    notify_completion(result);
}

Result

Target toolchain min date max date
F0,F3,F4,F7,LX uARM, ARM, GCC 1 Jan 1969 19 Jan 2038
F0,F3,F4,F7,LX IAR 1 Jan 1969 6 Feb 2036
F1 uARM, ARM, GCC 13 Dec 1901 19 Jan 2038
F1 IAR 13 Dec 1901 6 Feb 2036

@0xc0170
Copy link
Contributor

0xc0170 commented Jul 14, 2016

@mbed-bot: TEST

HOST_OSES=windows
BUILD_TOOLCHAINS=ARM,GCC_ARM,IAR
TARGETS=ALL

@0xc0170
Copy link
Contributor

0xc0170 commented Jul 14, 2016

Thanks for providing the detailed description, for future, part of it (or even all) can be included in the commit message.

LGTM

@mbed-bot
Copy link

[Build 625]
FAILURE: Something went wrong when building and testing.

@0xc0170 0xc0170 merged commit 1201f4a into ARMmbed:master Jul 15, 2016
@svastm svastm deleted the fix_rtc_min_year branch July 18, 2016 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants