Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Kconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ config FILE_SYSTEM
config FAT_FILESYSTEM_ELM
default y

config FS_FATFS_HAS_RTC
default y

config FS_FATFS_LFN
default y
choice FS_FATFS_LFN_MODE
Expand Down
1 change: 1 addition & 0 deletions prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ CONFIG_SDHC=y
CONFIG_LOG=y
CONFIG_FILE_SYSTEM=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_HAS_RTC=y

# Enable SDHC interface
CONFIG_DISK_DRIVERS=y
Expand Down
1 change: 1 addition & 0 deletions prj_fota.conf
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ CONFIG_SDHC=y
CONFIG_LOG=y
CONFIG_FILE_SYSTEM=y
CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_HAS_RTC=y

# Enable SDHC interface
CONFIG_DISK_DRIVERS=y
Expand Down
1 change: 1 addition & 0 deletions src/SD_Card/SD_Card_Manager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

target_sources(app PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/SD_Card_Manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fatfs_time.c
)
55 changes: 55 additions & 0 deletions src/SD_Card/SD_Card_Manager/fatfs_time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <ff.h>

#include "time_sync.h"

#define FAT_YEAR_MIN 1980U
#define FAT_YEAR_MAX 2107U
#define UNIX_US_PER_SECOND 1000000ULL
#define TM_YEAR_BASE 1900U /* struct tm.tm_year stores years since 1900. */

/* 2022-01-01 matches FatFs/Zephyr's no-RTC fallback date and is used until phone time sync is available. */
#define FATFS_FALLBACK_TIME \
(((DWORD)(2022U - FAT_YEAR_MIN) << 25) | ((DWORD)1U << 21) | ((DWORD)1U << 16))
Comment on lines +14 to +15

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use 2022-01-01 as the fallback time stamp? I would have expected 1980-01-01 as the minimum fatfs timestamp. A comment explaining the reasoning would be cool

@habibialireza habibialireza Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2022-01-01 is the default date used in this sdk. Before this fix, all files were created with this date. Comment will be added.



DWORD get_fattime(void)
{

uint64_t now_us;
uint64_t now_seconds;

if (!time_sync_is_synced()) {
return FATFS_FALLBACK_TIME;
}

now_us = get_current_time_us();
now_seconds = now_us / UNIX_US_PER_SECOND;


time_t now = (time_t)now_seconds;
struct tm calendar;

if ((uint64_t)now != now_seconds || gmtime_r(&now, &calendar) == NULL) {
return FATFS_FALLBACK_TIME;
}

uint32_t year = (uint32_t)calendar.tm_year + TM_YEAR_BASE;

if (year < FAT_YEAR_MIN || year > FAT_YEAR_MAX) {
return FATFS_FALLBACK_TIME;
}

/*
* FAT directory entries store timestamps as packed date/time fields.
* FatFs asks the application for that packed value via get_fattime().
*/
return (((DWORD)(year - FAT_YEAR_MIN) << 25) |
((DWORD)(calendar.tm_mon + 1) << 21) |
((DWORD)calendar.tm_mday << 16) |
((DWORD)calendar.tm_hour << 11) |
((DWORD)calendar.tm_min << 5) |
((DWORD)(calendar.tm_sec / 2)));
}
11 changes: 9 additions & 2 deletions src/time_sync/time_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <zephyr/devicetree.h>

#include <zephyr/kernel.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/byteorder.h>
#include <string.h>
#include <limits.h>
Expand Down Expand Up @@ -40,6 +41,7 @@ struct __packed time_sync_packet {
};

int64_t time_offset_us = 0;
static atomic_t time_synced;

bool notify_rtt_enabled = false;

Expand Down Expand Up @@ -137,6 +139,7 @@ static ssize_t write_time_offset(
int64_t delta;
memcpy(&delta, buf, sizeof(delta));
time_offset_us += delta;
atomic_set(&time_synced, 1);
LOG_DBG("Received time offset update: %lld us, new time offset: %lld us", delta, time_offset_us);

return len;
Expand All @@ -152,7 +155,11 @@ int init_time_sync(void) {
return 0;
}

inline uint64_t get_current_time_us() {
bool time_sync_is_synced(void) {
return atomic_get(&time_synced) != 0;
}

uint64_t get_current_time_us(void) {
uint64_t base_u = get_time_since_boot_us();
int64_t base_s = (base_u > (uint64_t)INT64_MAX) ? INT64_MAX : (int64_t)base_u;
int64_t now_s = base_s + time_offset_us;
Expand All @@ -167,7 +174,7 @@ inline uint64_t get_current_time_us() {
return (uint64_t)now_s;
}

inline uint64_t get_time_since_boot_us() {
uint64_t get_time_since_boot_us(void) {
return k_ticks_to_us_floor64(k_uptime_ticks());
}

Expand Down
13 changes: 10 additions & 3 deletions src/time_sync/time_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@
extern "C" {
#endif

#include <stdbool.h>
#include <stdint.h>

/**
* @brief Get time since boot in microseconds.
* @return Time since boot in microseconds.
*/
uint64_t get_time_since_boot_us();
uint64_t get_time_since_boot_us(void);

/**
* @brief Get the current synchronized time in microseconds (since 1. January 1970).
* @return Current synchronized time in microseconds.
*/
uint64_t get_current_time_us();
uint64_t get_current_time_us(void);

/**
* @brief Check whether the wall-clock time has been synchronized.
* @return True after the Time Offset characteristic has been written.
*/
bool time_sync_is_synced(void);

/**
* @brief Initialize the time synchronization module.
Expand All @@ -27,4 +34,4 @@ int init_time_sync();

#ifdef __cplusplus
}
#endif
#endif
Loading