text: /*
   * Copyright (c) 2006-2018, RT-Thread Development Team
   *
   * SPDX-License-Identifier: Apache-2.0
   *
   * Change Logs:
   * Date			Author		Notes
   * 2018-05-05   sundm75     first version
   */
  
  /* Includes ------------------------------------------------------------------*/
  #include "board.h"
  #include "drv_rtc.h"
  #include <rtdevice.h>
  
  #include "../libraries/ls1c_regs.h"
  #include "../libraries/ls1c_rtc.h"
  
  //#define RT_RTC_DEBUG
  
  #if defined(RT_USING_RTC)
  #ifdef RT_RTC_DEBUG
  #define rtc_debug(format,args...) 			rt_kprintf(format, ##args)
  #else
  #define rtc_debug(format,args...)
  #endif
  
  static struct rt_device rtc;
  
  RTC_TypeDef * RTC_Handler;  
  
  static time_t get_timestamp(void) 
  {
      struct tm tm_new = {0}; 
      RTC_TimeTypeDef rtcDate; 
      
      RTC_GetTime(RTC_Handler, &rtcDate); 
      
      tm_new.tm_sec  = rtcDate.Seconds; 
      tm_new.tm_min  = rtcDate.Minutes; 
      tm_new.tm_hour = rtcDate.Hours;
      
      tm_new.tm_mday = rtcDate.Date; 
      tm_new.tm_mon  = rtcDate.Month- 1; 
      tm_new.tm_year = rtcDate.Year + 2000 - 1900; 
  
      return mktime(&tm_new);
  }
  
  static int set_timestamp(time_t timestamp)
  {
      struct tm *p_tm;
      RTC_TimeTypeDef rtcDate; 
      
      p_tm = localtime(&timestamp);
      
      rtcDate.Seconds= p_tm->tm_sec ; 
      rtcDate.Minutes= p_tm->tm_min ; 
      rtcDate.Hours= p_tm->tm_hour; 
  
      rtcDate.Date= p_tm->tm_mday; 
      rtcDate.Month= p_tm->tm_mon  + 1;  
      rtcDate.Year= p_tm->tm_year + 1900 - 2000; 
      
      RTC_SetTime(RTC_Handler, &rtcDate); 
      rt_kprintf("\r\nrtcDate is %d.%d.%d - %d:%d:%d",rtcDate.Year, rtcDate.Month, rtcDate.Date, rtcDate.Hours, rtcDate.Minutes, rtcDate.Seconds);
      return RT_EOK;
  }
  
  rt_uint8_t RTC_Init(void)
  {      
      RTC_Handler = RTC; 
      return 0;
  }
  
  static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  {
      if (dev->rx_indicate != RT_NULL)
      {
          /* Open Interrupt */
      }
  
      return RT_EOK;
  }
  
  static rt_size_t rt_rtc_read(
      rt_device_t     dev,
      rt_off_t        pos,
      void*           buffer,
      rt_size_t       size)
  {
      
      return 0;
  }
  
   /**
   * This function configure RTC device.
   *
   * @param dev, pointer to device descriptor.
   * @param cmd, RTC control command.
   *
   * @return the error code.
   */
  static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
  {
      rt_err_t result;
      RT_ASSERT(dev != RT_NULL);
      switch (cmd)
      {
      case RT_DEVICE_CTRL_RTC_GET_TIME:
         
          *(rt_uint32_t *)args = get_timestamp();
          rtc_debug("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
          break;
  
      case RT_DEVICE_CTRL_RTC_SET_TIME:
      {
          result = set_timestamp(*(rt_uint32_t *)args);
          rtc_debug("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
      }
      break;
      }
  
      return result;
  }
  
   /**
   * This function register RTC device.
   *
   * @param device, pointer to device descriptor.
   * @param name, device name.
   * @param flag, configuration flags.
   *
   * @return the error code.
   */
  rt_err_t rt_hw_rtc_register(
      rt_device_t     device,
      const char      *name,
      rt_uint32_t     flag)
  {
      RT_ASSERT(device != RT_NULL);
  
      device->type        = RT_Device_Class_RTC;
      device->rx_indicate = RT_NULL;
      device->tx_complete = RT_NULL;
      device->init        = RT_NULL;
      device->open        = rt_rtc_open;
      device->close       = RT_NULL;
      device->read        = rt_rtc_read;
      device->write       = RT_NULL;
      device->control     = rt_rtc_control;
      device->user_data   = RT_NULL; /* no private */
  
      /* register a character device */
      return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  }
  
   /**
   * This function initialize RTC module related hardware and register RTC device to kernel.
   *
   * @param none.
   *
   * @return the error code.
   */
  int  rt_hw_rtc_init(void)
  {
      RTC_Init();
      /* register rtc device */
      rt_hw_rtc_register(&rtc, RT_RTC_NAME, 0);
      return RT_EOK;
  }
  INIT_BOARD_EXPORT(rt_hw_rtc_init);
  #endif
  
  
  
  
  