当前位置:网站首页>8. Realization of real-time data backup and real-time clock function
8. Realization of real-time data backup and real-time clock function
2022-07-28 15:34:00 【Turing_ three hundred and twenty-one】
\qquad Here is HD-GR GNSS Real time data backup and real-time clock function implementation code of navigation software :
// rtc.c -- Real time data backup and RTC functions.
/* * Copyright (C) 2005 Andrew Greenberg * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991). * See the "COPYING" file distributed with this software for more information. */
/* * HD-GR GNSS receiver project * Modes : None * version : V1.0 * date : xx/xx/2015 */
#include <io.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "includes.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_flash.h"
#include "sys/alt_sys_wrappers.h"
#include "rtc.h"
#define FLASH_BACKUP_REG 0
#define FLASH_BACKUP_OFS 0x200000
// DS32X35 RTC slave address
#define DS32X35_RTC_SLAVE_ADDRESS 0xd0
int m_rtc_inited = 0;
static int m_ic_ack = 0;
int flash_read_backup(int offset,void* dest_addr,int length)
{
int ret_code = -1;
alt_flash_fd* fd = alt_flash_open_dev(EPCS_FLASH_CONTROLLER_0_NAME);
if (fd) {
flash_region* regions;
int number_of_regions;
ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions);
if ((ret_code == 0) && (number_of_regions > FLASH_BACKUP_REG)) {
offset += FLASH_BACKUP_OFS;
ret_code = alt_read_flash(fd,
regions[FLASH_BACKUP_REG].offset+offset,
dest_addr,length);
}
alt_flash_close_dev(fd);
}
return ret_code;
}
int flash_write_backup(int offset,void* dest_addr,int length)
{
int ret_code = -1;
alt_flash_fd* fd = alt_flash_open_dev(EPCS_FLASH_CONTROLLER_0_NAME);
if (fd) {
flash_region* regions;
int number_of_regions;
ret_code = alt_get_flash_info(fd, ®ions, &number_of_regions);
if ((ret_code == 0) && (number_of_regions > FLASH_BACKUP_REG)) {
offset += FLASH_BACKUP_OFS;
ret_code = alt_write_flash_block(fd,
regions[FLASH_BACKUP_REG].offset,
regions[FLASH_BACKUP_REG].offset+offset,
dest_addr,length);
}
alt_flash_close_dev(fd);
}
return ret_code;
}
int cycgps_init_backup(void)
{
int ret_code = -1;
flash_backup_t *pfb = (flash_backup_t *)malloc(sizeof(flash_backup_t));
memset(m_gps_alm, 0, sizeof(m_gps_alm));
if (pfb) {
if (flash_read_backup(0, pfb, sizeof(flash_backup_t)) == 0) {
if (pfb->header.signature == BACKUP_HEADER_SIGNATURE &&
pfb->header.data_size == sizeof(flash_backup_t)) {
m_current_pvt = pfb->body.rec_pvt;
m_current_neu = pfb->body.rec_neu;
memcpy(m_gps_alm, pfb->body.gps_alm, sizeof(m_gps_alm));
ret_code = 0;
}
}
free(pfb);
}
return ret_code;
}
int cycgps_save_backup(void)
{
int ret_code = -1;
flash_backup_t *pfb = (flash_backup_t *)malloc(sizeof(flash_backup_t));
if (pfb) {
pfb->header.signature = BACKUP_HEADER_SIGNATURE;
pfb->header.data_size = sizeof(flash_backup_t);
pfb->header.data_time = get_standard_time();
pfb->body.rec_pvt = m_current_pvt;
pfb->body.rec_neu = m_current_neu;
memcpy(pfb->body.gps_alm, m_gps_alm, sizeof(m_gps_alm));
ret_code = flash_write_backup(0, pfb, sizeof(flash_backup_t));
free(pfb);
}
return ret_code;
}
/* * Name: iic_start * Description: IIC start-up */
void iic_start(void)
{
// Send data signal of starting condition
IOWR_ALTERA_AVALON_PIO_DIRECTION(RTC_SDA_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, 1);
// Send the clock signal of the starting condition
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 1);
// The establishment time of starting condition is greater than 4.7us Time delay
ALT_USLEEP(10);
// Send start signal
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, 0);
// The holding time of starting condition is greater than 4us
ALT_USLEEP(5);
// Hold on IIC Bus , Ready to send or receive data
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
ALT_USLEEP(5);
}
/* * Name: iic_stop * Description: IIC stop it */
void iic_stop(void)
{
// Send the data signal of the stop condition
IOWR_ALTERA_AVALON_PIO_DIRECTION(RTC_SDA_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, 0);
// Send the clock signal of the stop condition
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
ALT_USLEEP(10);
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 1);
// Stop condition establishment time is greater than 4us
ALT_USLEEP(5);
// Send stop signal
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, 1);
ALT_USLEEP(10);
}
/* * Name: iic_write * Description: IIC Write a byte */
void iic_write(alt_u8 dat)
{
alt_u8 i, tmp;
IOWR_ALTERA_AVALON_PIO_DIRECTION(RTC_SDA_BASE, 1);
for(i=0; i<8; i++) {
// Send data bits
tmp = (dat & 0x80) ? 1 : 0;
dat <<= 1;
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, tmp);
ALT_USLEEP(5);
// Set the clock line to high , Inform the controller to start receiving data bits
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 1);
// Ensure that the clock high-level cycle is greater than 4us
ALT_USLEEP(10);
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
ALT_USLEEP(5);
}
// 8 Release the data line after the bit is sent , Ready to receive reply bit
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, 1);
ALT_USLEEP(5);
IOWR_ALTERA_AVALON_PIO_DIRECTION(RTC_SDA_BASE, 0);
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 1);
ALT_USLEEP(5);
// Receive response bit
tmp = IORD_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE);
m_ic_ack = (tmp == 1) ? 0:1;
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
ALT_USLEEP(5);
}
/* * Name: iic_read * Description: IIC Read a byte */
alt_u8 iic_read(void)
{
alt_u8 i, dat = 0;
IOWR_ALTERA_AVALON_PIO_DIRECTION(RTC_SDA_BASE, 0);
for(i=0; i<8; i++) {
// Set clock line to low , Ready to receive data bits
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
// The clock low-level cycle is greater than 4.7us
ALT_USLEEP(10);
// Set the clock line to high , Make data online effective
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 1);
ALT_USLEEP(5);
// Read data bit
dat <<= 1;
dat |= IORD_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE);
ALT_USLEEP(5);
}
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
ALT_USLEEP(5);
return dat;
}
/* * Name: iic_ack * Description: issue IIC Answer or non answer signal */
void iic_ack(int a)
{
// Send an answer or non answer signal
IOWR_ALTERA_AVALON_PIO_DIRECTION(RTC_SDA_BASE, 1);
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SDA_BASE, (a == 0)? 0:1);
ALT_USLEEP(5);
// The clock high-level cycle is greater than 4us
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 1);
ALT_USLEEP(5);
// Clear the clock line , Hold on IIC Bus to continue receiving
IOWR_ALTERA_AVALON_PIO_DATA(RTC_SCL_BASE, 0);
ALT_USLEEP(5);
}
/* * Name: rtc_write_byte * Description: towards RTC Write a byte * Return: 1 It means success */
int rtc_write_byte(alt_u8 addr, alt_u8 dat)
{
// Start the bus
iic_start();
// Send device address
iic_write(addr);
if (m_ic_ack == 0) {
return 0;
}
// send data
iic_write(dat);
if (m_ic_ack == 0) {
return 0;
}
// End the bus
iic_stop();
return 1;
}
/* * Name: rtc_write_multibytes * Description: towards RTC Write multiple bytes * Return: 1 It means success */
int rtc_write_multibytes(alt_u8 addr, alt_u8 suba, alt_u8 *dat, int no)
{
int i;
// Start the bus
iic_start();
// Send device address
iic_write(addr);
if (m_ic_ack == 0) {
return 0;
}
// Sender sub address
iic_write(suba);
if (m_ic_ack == 0) {
return 0;
}
// send data
for (i = 0; i < no; i ++) {
iic_write(dat[i]);
if (m_ic_ack == 0) {
return 0;
}
}
// End the bus
iic_stop();
return 1;
}
/* * Name: rtc_read_byte * Description: from RTC Read a byte * Return: 1 It means success */
int rtc_read_byte(alt_u8 addr, alt_u8 *c)
{
// Start the bus
iic_start();
// Send device address
iic_write(addr+1);
if (m_ic_ack == 0) {
return 0;
}
// Reading data
*c = iic_read();
// Send non reply bit
iic_ack(1);
iic_stop();
return 1;
}
/* * Name: rtc_read_multibytes * Description: from RTC Read multiple bytes * Return: 1 It means success */
int rtc_read_multibytes(alt_u8 addr, alt_u8 suba, alt_u8 *dat, int no)
{
int i;
// Start the bus
iic_start();
// Send device address
iic_write(addr);
if (m_ic_ack == 0) {
return 0;
}
// Sender sub address
iic_write(suba);
if (m_ic_ack == 0) {
return 0;
}
iic_start();
iic_write(addr+1);
if (m_ic_ack == 0) {
return 0;
}
// receive data
for (i = 0; i < no-1; i ++) {
// Receiving byte
dat[i]= iic_read();
// Send reply bit
iic_ack(0);
}
dat[i]= iic_read();
// Send non reply bit
iic_ack(1);
iic_stop();
return 1;
}
/* * Description: Set time information * Return: 1 It means success */
int ds32x35_set_time(stdtime_t st, double gsts)
{
alt_u8 val, ti[7];
val = (alt_u8)st.seconds;
ti[0] = ((val/16) << 4) + val%16;
ti[1] = (alt_u8)(((st.minutes/16) << 4) + st.minutes%16);
ti[2] = (alt_u8)(((st.hours/16) << 4) + st.hours%16);
ti[3] = (alt_u8)((int)gsts/86400) + 1;
ti[4] = (alt_u8)(((st.days/16) << 4) + st.days%16);
ti[5] = (alt_u8)(((st.months/16) << 4) + st.months%16);
val = (alt_u8)(st.years - 2000);
ti[6] = ((val/16) << 4) + val%16;
return rtc_write_multibytes(DS32X35_RTC_SLAVE_ADDRESS, 0, ti, 7);
}
/* * Description: Get time information * Return: 1 It means success */
int ds32x35_get_time(stdtime_t *pst)
{
int result;
alt_u8 ti[7];
result = rtc_read_multibytes(DS32X35_RTC_SLAVE_ADDRESS, 0, ti, 7);
if (result != 0) {
if (ti[6] == 0) {
result = 0;
}
else if (pst) {
pst->seconds= (ti[0] >> 4)*10 + ti[0]%16;
pst->minutes= (ti[1] >> 4)*10 + ti[1]%16;
pst->hours = (ti[2] >> 4)*10 + ti[2]%16;
pst->days = (ti[4] >> 4)*10 + ti[4]%16;
pst->months = (ti[5] >> 4)*10 + ti[5]%16;
pst->years = (ti[6] >> 4)*10 + ti[6]%16 + 2000;
}
}
return result;
}
/* * Description: Check the time setting , If not set , Set when possible * Return: 1 Indicates that it is set , 0 Means to keep the existing settings ,-1 Indicates an error */
int ds32x35_check_set_time(void)
{
if (m_rtc_inited == 0 && get_clock_state() >= SF1_CLOCK) {
int result = ds32x35_set_time(
get_standard_time(),
get_time_in_seconds());
m_rtc_inited = (result > 0) ? 1:-1;
}
return m_rtc_inited;
}
边栏推荐
- No files or folders found to process
- 设置结构体字节对齐
- Customer service system attached to crmeb Standard Edition
- How many tips do you know about using mock technology to help improve test efficiency?
- leetcode-括号有效性问题
- Shellcode writing (unfinished)
- Principle and configuration of MPLS LDP
- QCustomPlot绘图工具常用方法
- subst命令将一个文件夹镜像成本地的一个磁盘
- MIT指出公开预训练模型不能乱用
猜你喜欢

MPLS LDP的原理与配置

Explain the difference set, intersection set and union set of complex type set in detail.Net

No files or folders found to process

Grpc protocol buffer

Execution process of SQL statement

800V高压系统

腾讯面试之--请你设计一个实现线程池顺序执行

堆操作
![PMP [agile textbook + full truth simulation question]. After the exam on June 25, agile has become the top priority](/img/72/d3e46a820796a48b458cd2d0a18f8f.png)
PMP [agile textbook + full truth simulation question]. After the exam on June 25, agile has become the top priority

Shellcode writing (unfinished)
随机推荐
ECCV 2022 | SSP: 自支持匹配的小样本任务新思想
Write a standard character device driver with your hands
Qt信号与槽的五种连接方式
封装统一返回对象MessageResult
Crmeb v4.3 deployment process
DAY:7/11
1、开源GPS项目HD-GR GNSS的著作者
Leetcode - number of operations, non repeating numbers, diagonal traversal, Joseph Ring
10、相关数据累积任务实现
使用Mock技术帮助提升测试效率的小tips,你知道几个?
4. Main program and cumulative interrupt processing routine implementation code
subst命令将一个文件夹镜像成本地的一个磁盘
MATLAB不覆盖导入EXCEL
Back compilation failed
详解.NET的求复杂类型集合的差集、交集、并集
Knowledge payment open source system
R introduction example details
What are the functions to be added in crmeb pro2.2?
爬虫入门(1)——requests(1)
提速1200倍!MIT开发新一代药物研发AI,吊打老模型