machine_rtc.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2017 "Eric Poulsen" <eric@zyxod.com>
  7. * Copyright (c) 2017 "Tom Manning" <tom@manningetal.com>
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <time.h>
  30. #include <sys/time.h>
  31. #include "driver/gpio.h"
  32. #include "py/nlr.h"
  33. #include "py/obj.h"
  34. #include "py/runtime.h"
  35. #include "py/mphal.h"
  36. #include "timeutils.h"
  37. #include "modmachine.h"
  38. #include "machine_rtc.h"
  39. typedef struct _machine_rtc_obj_t {
  40. mp_obj_base_t base;
  41. } machine_rtc_obj_t;
  42. #define MEM_MAGIC 0x75507921
  43. /* There is 8K of rtc_slow_memory, but some is used by the system software
  44. If the USER_MAXLEN is set to high, the following compile error will happen:
  45. region `rtc_slow_seg' overflowed by N bytes
  46. The current system software allows almost 4096 to be used.
  47. To avoid running into issues if the system software uses more, 2048 was picked as a max length
  48. */
  49. #define MEM_USER_MAXLEN 2048
  50. RTC_DATA_ATTR uint32_t rtc_user_mem_magic;
  51. RTC_DATA_ATTR uint32_t rtc_user_mem_len;
  52. RTC_DATA_ATTR uint8_t rtc_user_mem_data[MEM_USER_MAXLEN];
  53. // singleton RTC object
  54. STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}};
  55. machine_rtc_config_t machine_rtc_config = {
  56. .ext1_pins = 0,
  57. .ext0_pin = -1
  58. };
  59. STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  60. // check arguments
  61. mp_arg_check_num(n_args, n_kw, 0, 0, false);
  62. // return constant object
  63. return (mp_obj_t)&machine_rtc_obj;
  64. }
  65. STATIC mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *args) {
  66. if (n_args == 1) {
  67. // Get time
  68. struct timeval tv;
  69. gettimeofday(&tv, NULL);
  70. timeutils_struct_time_t tm;
  71. timeutils_seconds_since_2000_to_struct_time(tv.tv_sec, &tm);
  72. mp_obj_t tuple[8] = {
  73. mp_obj_new_int(tm.tm_year),
  74. mp_obj_new_int(tm.tm_mon),
  75. mp_obj_new_int(tm.tm_mday),
  76. mp_obj_new_int(tm.tm_wday),
  77. mp_obj_new_int(tm.tm_hour),
  78. mp_obj_new_int(tm.tm_min),
  79. mp_obj_new_int(tm.tm_sec),
  80. mp_obj_new_int(tv.tv_usec)
  81. };
  82. return mp_obj_new_tuple(8, tuple);
  83. } else {
  84. // Set time
  85. mp_obj_t *items;
  86. mp_obj_get_array_fixed_n(args[1], 8, &items);
  87. struct timeval tv = {0};
  88. tv.tv_sec = timeutils_seconds_since_2000(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5]), mp_obj_get_int(items[6]));
  89. settimeofday(&tv, NULL);
  90. return mp_const_none;
  91. }
  92. }
  93. STATIC mp_obj_t machine_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
  94. return machine_rtc_datetime_helper(n_args, args);
  95. }
  96. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_datetime_obj, 1, 2, machine_rtc_datetime);
  97. STATIC mp_obj_t machine_rtc_init(mp_obj_t self_in, mp_obj_t date) {
  98. mp_obj_t args[2] = {self_in, date};
  99. machine_rtc_datetime_helper(2, args);
  100. if (rtc_user_mem_magic != MEM_MAGIC) {
  101. rtc_user_mem_magic = MEM_MAGIC;
  102. rtc_user_mem_len = 0;
  103. }
  104. return mp_const_none;
  105. }
  106. STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_rtc_init_obj, machine_rtc_init);
  107. STATIC mp_obj_t machine_rtc_memory(mp_uint_t n_args, const mp_obj_t *args) {
  108. if (n_args == 1) {
  109. // read RTC memory
  110. uint32_t len = rtc_user_mem_len;
  111. uint8_t rtcram[MEM_USER_MAXLEN];
  112. memcpy( (char *) rtcram, (char *) rtc_user_mem_data, len);
  113. return mp_obj_new_bytes(rtcram, len);
  114. } else {
  115. // write RTC memory
  116. mp_buffer_info_t bufinfo;
  117. mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
  118. if (bufinfo.len > MEM_USER_MAXLEN) {
  119. mp_raise_ValueError("buffer too long");
  120. }
  121. memcpy( (char *) rtc_user_mem_data, (char *) bufinfo.buf, bufinfo.len);
  122. rtc_user_mem_len = bufinfo.len;
  123. return mp_const_none;
  124. }
  125. }
  126. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_rtc_memory_obj, 1, 2, machine_rtc_memory);
  127. STATIC const mp_rom_map_elem_t machine_rtc_locals_dict_table[] = {
  128. { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_rtc_datetime_obj) },
  129. { MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&machine_rtc_datetime_obj) },
  130. { MP_ROM_QSTR(MP_QSTR_memory), MP_ROM_PTR(&machine_rtc_memory_obj) },
  131. };
  132. STATIC MP_DEFINE_CONST_DICT(machine_rtc_locals_dict, machine_rtc_locals_dict_table);
  133. const mp_obj_type_t machine_rtc_type = {
  134. { &mp_type_type },
  135. .name = MP_QSTR_RTC,
  136. .make_new = machine_rtc_make_new,
  137. .locals_dict = (mp_obj_t)&machine_rtc_locals_dict,
  138. };