/** ****************************************************************************** * @file rtc_io.c * @author AMG Energy Solution Team * @version V1.0.0 * @date 07-Feb-2022 * @brief This file provides all the code of the realtime clock functions. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *

© COPYRIGHT 2022 AMG

****************************************************************************** */ ////////////////////////////////////////////////////////////////////////// //// DS1302.C //// //// Driver for Real Time Clock //// //// //// //// rtc_init() Call after power up//// //// //// //// rtc_set_datetime(day,mth,year,dow,hour,min) Set the date/time //// //// //// //// rtc_get_date(day,mth,year,dow) Get the date //// //// //// //// rtc_get_time(hr,min,sec) Get the time //// //// //// //// rtc_write_nvr(address,data) Write to NVR //// //// //// //// data = rtc_read_nvr(address) Read from NVR //// //// //// ////////////////////////////////////////////////////////////////////////// //// (C) Copyright 1996,2003 Custom Computer Services //// //// This source code may only be used by licensed users of the CCS C //// //// compiler. This source code may only be distributed to other //// //// licensed users of the CCS C compiler. No other use, reproduction//// //// or distribution is permitted without written permission. //// //// Derivative programs created using this software in object code //// //// form are not restricted in any way. //// ////////////////////////////////////////////////////////////////////////// /** @addtogroup mBMS2 * @{ */ /* Includes ------------------------------------------------------------------*/ #include "rtc_io.h" #include "delay.h" #include "stdio.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* RTC IO Port/Pin definition */ #define RTC_IO_CLK_PORT (PortD) #define RTC_IO_CLK_PIN (Pin11) #define RTC_IO_DAT_PORT (PortD) #define RTC_IO_DAT_PIN (Pin10) #define RTC_IO_RST_PORT (PortD) #define RTC_IO_RST_PIN (Pin09) // -------------------------------------------------------------------------------- // RTC-Bus-Line // -------------------------------------------------------------------------------- #define RTC_CLK_LOW PORT_ResetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN) // rtc data line Low-Level #define RTC_CLK_HIGH PORT_SetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN) // rtc data line High-Level #define RTC_DAT_LOW PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line Low-Level #define RTC_DAT_HIGH PORT_SetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line High-Level #define RTC_DAT_IN PORT_GetBit(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line read #define RTC_RST_LOW PORT_ResetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN) // rtc data line Low-Level #define RTC_RST_HIGH PORT_SetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN) // rtc data line High-Level #define CLK_DIV 10 #define Tdc 200 / CLK_DIV // Min. #define Tcdh 280 / CLK_DIV // Min. #define Tcdd 800 / CLK_DIV // Max. #define Tcl 1000 / CLK_DIV // Min. #define Tch 1000 / CLK_DIV // Min. #define Tcc 4000 / CLK_DIV // Min. #define Tcch 240 / CLK_DIV // Min. #define Tcwh 4000 / CLK_DIV // Min. #define Tcdz 280 / CLK_DIV // Max. #define Tccz 280 / CLK_DIV // Max. #define RD_ADDR_RTC_YEAR 0x8D #define RD_ADDR_RTC_MONTH 0x89 #define RD_ADDR_RTC_DATE 0x87 #define RD_ADDR_RTC_WDAY 0x8B #define RD_ADDR_RTC_HOUR 0x85 #define RD_ADDR_RTC_MIN 0x83 #define RD_ADDR_RTC_SEC 0x81 #define WR_ADDR_RTC_YEAR 0x8C #define WR_ADDR_RTC_MONTH 0x88 #define WR_ADDR_RTC_DATE 0x86 #define WR_ADDR_RTC_WDAY 0x8A #define WR_ADDR_RTC_HOUR 0x84 #define WR_ADDR_RTC_MIN 0x82 #define WR_ADDR_RTC_SEC 0x80 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private prototype functions -----------------------------------------------*/ // send 'databyte' to 'port' void outp(uint8_t HighLow); // read byte from 'port' uint8_t inp(void); // 1-Wire Timing Generation // Pause for exactly 'tick' number of ticks = 0.25us void tickDelay(uint16_t tick); // Implementation is platform specific //----------------------------------------------------------------------------- // Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0). // /* Private functions ---------------------------------------------------------*/ void tickDelay(uint16_t tick) { delay_us(tick); } void RTC_IO_Config(void) { stc_port_init_t stcPortInit; /* configuration structure initialization */ MEM_ZERO_STRUCT(stcPortInit); stcPortInit.enPinMode = Pin_Mode_Out; stcPortInit.enExInt = Disable; stcPortInit.enPullUp = Disable; /* LED Port/Pin initialization */ PORT_Init(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN, &stcPortInit); PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit); PORT_Init(RTC_IO_RST_PORT, RTC_IO_RST_PIN, &stcPortInit); PORT_ResetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN); PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN); PORT_ResetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN); } void rtc_dat_config(uint8_t inout) { stc_port_init_t stcPortInit; /* configuration structure initialization */ MEM_ZERO_STRUCT(stcPortInit); if (inout == 1) { // Output stcPortInit.enPinMode = Pin_Mode_Out; stcPortInit.enExInt = Disable; stcPortInit.enPullUp = Disable; PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN); PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit); } else { // Input stcPortInit.enPinMode = Pin_Mode_In; stcPortInit.enExInt = Disable; stcPortInit.enPullUp = Disable; PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit); } } void outp(uint8_t HighLow) { if (HighLow) RTC_DAT_HIGH; else RTC_DAT_LOW; } uint8_t inp(void) { return RTC_DAT_IN; } void write_ds1302_byte(uint8_t cmd) { uint8_t i; for (i = 0; i < 8; i++) { outp((cmd >> i) & 0x01); delay_ns(Tcl); RTC_CLK_HIGH; delay_ns(Tch); RTC_CLK_LOW; } } void write_ds1302(uint8_t cmd, uint8_t data) { rtc_dat_config(1); RTC_RST_HIGH; delay_ns(Tcc); write_ds1302_byte(cmd); write_ds1302_byte(data); RTC_RST_LOW; delay_ns(Tcwh); } uint8_t read_ds1302(uint8_t cmd) { uint8_t data = 0; rtc_dat_config(1); if (cmd == 0) cmd = cmd; RTC_RST_HIGH; delay_ns(Tcc - Tcl); write_ds1302_byte(cmd); rtc_dat_config(0); for (int i = 0; i < 8; i++) { delay_ns(Tcdd); data |= (inp() << i); delay_ns(Tcl-Tcdd); RTC_CLK_HIGH; delay_ns(Tch); RTC_CLK_LOW; } RTC_RST_LOW; rtc_dat_config(1); delay_ns(Tcwh); return (data); } void rtc_init(void) { uint8_t x; RTC_IO_Config(); RTC_RST_HIGH; delay_ns(Tch); RTC_CLK_LOW; write_ds1302(0x8e, 0); write_ds1302(0x90, 0xa6); x = read_ds1302(0x81); if ((x & 0x80) != 0) write_ds1302(0x80, 0); } uint8_t bcd2byte(uint8_t bcd) { return ((bcd >> 4) * 10) + (bcd & 0x0F); } uint8_t byte2bcd(uint8_t byte) { return ((byte / 10) << 4) + (byte % 10); } void rtc_set_datetime(uint8_t *DateTime) { int i = 0; write_ds1302(WR_ADDR_RTC_YEAR , byte2bcd(DateTime[i++])); write_ds1302(WR_ADDR_RTC_MONTH, byte2bcd(DateTime[i++])); write_ds1302(WR_ADDR_RTC_DATE , byte2bcd(DateTime[i++])); write_ds1302(WR_ADDR_RTC_HOUR , byte2bcd(DateTime[i++])); write_ds1302(WR_ADDR_RTC_MIN , byte2bcd(DateTime[i++])); write_ds1302(WR_ADDR_RTC_SEC , byte2bcd(DateTime[i++])); } void rtc_get_datetime(uint8_t *DateTime) { int i = 0; DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_YEAR)); DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_MONTH)); DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_DATE)); DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_WDAY)); DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_HOUR)); DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_MIN)); DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_SEC)); } uint8_t rtc_get_year(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_YEAR)); } uint8_t rtc_get_month(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_MONTH)); } uint8_t rtc_get_date(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_DATE)); } uint8_t rtc_get_wday(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_WDAY)); } uint8_t rtc_get_hour(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_HOUR)); } uint8_t rtc_get_min(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_MIN)); } uint8_t rtc_get_sec(void) { return bcd2byte(read_ds1302(RD_ADDR_RTC_SEC)); } void rtc_get_date1(uint8_t *day, uint8_t *mth, uint8_t *year, uint8_t *dow) { *day = read_ds1302(0x87); *mth = read_ds1302(0x89); *year = read_ds1302(0x8d); *dow = read_ds1302(0x8b); } void rtc_get_time(uint8_t *hr, uint8_t *min, uint8_t *sec) { *hr = read_ds1302(0x85); *min = read_ds1302(0x83); *sec = read_ds1302(0x81); } void rtc_write_nvr(uint8_t address, uint8_t data) { write_ds1302((address << 1) | 0xc0, data); } uint8_t rtc_read_nvr(uint8_t address) { return (read_ds1302((address << 1) | 0xc1)); } /*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/