368 lines
10 KiB
C
368 lines
10 KiB
C
/**
|
|
******************************************************************************
|
|
* @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.
|
|
*
|
|
* <h2><center>© COPYRIGHT 2022 AMG</center></h2>
|
|
******************************************************************************
|
|
*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//// 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******/
|