diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 99af1a5f..8f08b7a0 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -9,6 +9,7 @@ list(APPEND ADD_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/partition" "${CMAKE_CURRENT_SOURCE_DIR}/bl_math" "${CMAKE_CURRENT_SOURCE_DIR}/pid" +"${CMAKE_CURRENT_SOURCE_DIR}/timestamp" ) ####################################################### @@ -27,6 +28,7 @@ file(GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/partition/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/bl_math/*.c" "${CMAKE_CURRENT_SOURCE_DIR}/pid/*.c" +"${CMAKE_CURRENT_SOURCE_DIR}/timestamp/*.c" ) #aux_source_directory(. sources) diff --git a/common/timestamp/timestamp.c b/common/timestamp/timestamp.c new file mode 100644 index 00000000..606bafd1 --- /dev/null +++ b/common/timestamp/timestamp.c @@ -0,0 +1,137 @@ +/** + * @file timestamp.c + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ + +#include "timestamp.h" +#include "misc.h" + +#define FOUR_YEAR_DAY ((365 << 2) + 1) //The total number of days in a 4-year cycle +#define TIMEZONE (8) //Beijing time Zone adjustment + +#define SEC_NUM_PER_DAY (24 * 60 * 60) +#define SEC_NUM_PER_HOUR (60 * 60) +#define SEC_NUM_PER_MINUTE (60) + +static uint8_t month_day[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //平年 +static uint8_t Leap_month_day[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //闰年 + +/** +* @bref judge if it is a leap year +* @para year to be judge +* @return 1:leap year 0: nonleap year +*/ +bool check_leap_year(uint16_t year) +{ + if (year % 4) { + return false; + } else { + if ((year % 100 == 0) && (year % 400 != 0)) { + return false; + } else { + return true; + } + } +} + +void cal_weekday(rtc_time *beijing_time) +{ + uint32_t y,m,d,w; + + y=beijing_time->year; + m=beijing_time->month; + d=beijing_time->day; + + if((m==1)||(m==2)) + { + m+=12; + y--; + } + /* + 把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。 + 以公元元年为参考,公元元年1月1日为星期一
程序如下:
+	利用基姆拉尔森计算日期公式  w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)
+	*/
+	w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
+
+	beijing_time->week=(uint8_t)w;
+}
+
+void unixtime2bejingtime(uint32_t unixtime, rtc_time *beijing_time)
+{
+    uint32_t totle_day_num;
+    uint32_t current_sec_num;
+
+    uint16_t remain_day;
+
+    uint16_t temp_year;
+
+    uint8_t *p = NULL;
+
+    totle_day_num = unixtime / SEC_NUM_PER_DAY;   //The total number of days
+    current_sec_num = unixtime % SEC_NUM_PER_DAY; //The number of seconds this day
+
+    /* use the number of seconds this day, To calculate hour\minute\second */
+    beijing_time->hour = current_sec_num / SEC_NUM_PER_HOUR;
+    beijing_time->minute = (current_sec_num % SEC_NUM_PER_HOUR) / SEC_NUM_PER_MINUTE;
+    beijing_time->second = (current_sec_num % SEC_NUM_PER_HOUR) % SEC_NUM_PER_MINUTE;
+
+    /* Adjust the time zone and check whether the date is +1 */
+    beijing_time->hour += 8;
+    if (beijing_time->hour > 23) {
+        beijing_time->hour -= 24;
+        totle_day_num++;
+    }
+
+
+    /* calculate year */
+    beijing_time->year = 1970 + (totle_day_num / FOUR_YEAR_DAY) * 4; // 4-year as a cycle
+    remain_day = totle_day_num % FOUR_YEAR_DAY;                      //remaining day nym( < 4 year )
+
+    /* calculate year & day */
+    temp_year = check_leap_year(beijing_time->year) ? 366 : 365;
+    while (remain_day >= temp_year) {
+        beijing_time->year++;
+        remain_day -= temp_year;
+        temp_year = check_leap_year(beijing_time->year) ? 366 : 365;
+    }
+
+    /* Calculate specific dates(month\day)*/
+    p = check_leap_year(beijing_time->year) ? Leap_month_day : month_day;
+    remain_day++; //The actual day starts at 1
+    beijing_time->month = 0;
+    while (remain_day > *(p + beijing_time->month)) {
+        remain_day -= *(p + beijing_time->month);
+        beijing_time->month++;
+    }
+
+    beijing_time->month++; //The actual month starts at 1
+    beijing_time->day = remain_day;
+
+
+	
+	/*利用基姆拉尔森计算日期公式  w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)*/
+
+	beijing_time->week = beijing_time->day + 2*beijing_time->month + 3*(beijing_time->month+1)/5 + \
+	beijing_time->year + beijing_time->year/4 - beijing_time->year/100 +beijing_time->year/400 ;
+
+	cal_weekday(beijing_time);
+}
diff --git a/common/timestamp/timestamp.h b/common/timestamp/timestamp.h
new file mode 100644
index 00000000..2522d0f3
--- /dev/null
+++ b/common/timestamp/timestamp.h
@@ -0,0 +1,43 @@
+/**
+ * @file timestamp.h
+ * @brief
+ *
+ * Copyright (c) 2021 Bouffalolab team
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#ifndef _TIMESTAMP_
+#define _TIMESTAMP_
+
+#include "stdint.h"
+#include "stdbool.h" 
+
+typedef struct _rtc_time_t
+{
+	uint16_t year;
+	uint8_t month;
+	uint8_t day;
+	uint8_t week;
+	uint8_t hour;
+	uint8_t minute;
+	uint8_t second;
+}rtc_time;
+void unixtime2bejingtime(uint32_t unixtime,rtc_time* beijing_time);
+
+#endif
+
+
diff --git a/examples/rtc/rtc_calendar/CMakeLists.txt b/examples/rtc/rtc_calendar/CMakeLists.txt
new file mode 100644
index 00000000..64fc817d
--- /dev/null
+++ b/examples/rtc/rtc_calendar/CMakeLists.txt
@@ -0,0 +1,2 @@
+set(mains main.c)
+generate_bin()
\ No newline at end of file
diff --git a/examples/rtc/rtc_calendar/main.c b/examples/rtc/rtc_calendar/main.c
new file mode 100644
index 00000000..d32051ed
--- /dev/null
+++ b/examples/rtc/rtc_calendar/main.c
@@ -0,0 +1,41 @@
+/**
+ * @file main.c
+ * @brief
+ *
+ * Copyright (c) 2021 Bouffalolab team
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "hal_rtc.h"
+#include "timestamp.h"
+
+int main(void)
+{
+    rtc_time beijing_time;
+
+    bflb_platform_init(0);
+    rtc_init(0);                   //set 0 means comparing none
+    rtc_set_timestamp(1628074512); //1628074512 :2021-8-4 18:55:12
+    while (1) {
+        bflb_platform_delay_ms(1000);
+        unixtime2bejingtime((uint32_t)rtc_get_timestamp(), &beijing_time);
+        MSG("%d/%02d/%02d-%02d:%02d:%02d convert is: %u\r\n",
+            beijing_time.year, beijing_time.month, beijing_time.day,
+            beijing_time.hour, beijing_time.minute, beijing_time.second, (uint32_t)rtc_get_timestamp());
+    }
+}