kendryte-standalone-sdk/lib/firmware/sd3068.c

196 lines
4.5 KiB
C

/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "sd3068.h"
#include "fpioa.h"
#include "common.h"
#include "sysctl.h"
#include "i2c.h"
uint8_t i2c_bus_no = 0;
void sd3068_init(uint8_t sel)
{
i2c_bus_no = sel;
}
static int sd3068_write_reg(uint8_t reg, uint8_t *data_buf, uint8_t length)
{
i2c_write_reg(i2c_bus_no, reg, data_buf, length);
return 0;
}
static int sd3068_write_reg_dma(uint8_t reg, uint8_t *data_buf, uint8_t length)
{
i2c_write_reg_dma(DMAC_CHANNEL0, i2c_bus_no, reg, data_buf, length);
return 0;
}
static int sd3068_read_reg(uint8_t reg, uint8_t *data_buf, uint8_t length)
{
i2c_read_reg(i2c_bus_no, reg, data_buf, length);
return 0;
}
static int sd3068_read_reg_dma(uint8_t reg, uint8_t *data_buf, uint8_t length)
{
i2c_read_reg_dma(DMAC_CHANNEL0, DMAC_CHANNEL1, i2c_bus_no, reg, data_buf, length);
return 0;
}
static uint8_t hex2bcd(uint8_t data)
{
return data / 10 * 16 + data % 10;
}
static uint8_t bcd2hex(uint8_t data)
{
return data / 16 * 10 + data % 16;
}
int sd3068_write_enable(void)
{
uint8_t data[2] = {0};
data[0] = 0xFF;
data[1] = 0x80;
sd3068_write_reg(0x10, &data[1], 1);
sd3068_write_reg(0x0F, &data[0], 1);
return 0;
}
int sd3068_write_enable_dma(void)
{
uint8_t data[2] = {0};
data[0] = 0xFF;
data[1] = 0x80;
sd3068_write_reg_dma(0x10, &data[1], 1);
sd3068_write_reg_dma(0x0F, &data[0], 1);
return 0;
}
int sd3068_write_disable(void)
{
uint8_t data[2] = {0};
data[0] = 0x7B;
data[1] = 0;
sd3068_write_reg(0x0F, data, 2);
return 0;
}
int sd3068_write_data(uint8_t addr, uint8_t *data_buf, uint8_t length)
{
addr = ((addr <= 69) ? addr : 69);
length = ((length <= 70 - addr) ? length : 70 - addr);
sd3068_write_reg(0x2C + addr, data_buf, length);
return 0;
}
int sd3068_write_data_dma(uint8_t addr, uint8_t *data_buf, uint8_t length)
{
addr = ((addr <= 69) ? addr : 69);
length = ((length <= 70 - addr) ? length : 70 - addr);
sd3068_write_reg_dma(0x2C + addr, data_buf, length);
return 0;
}
int sd3068_read_data(uint8_t addr, uint8_t *data_buf, uint8_t length)
{
addr = ((addr <= 69) ? addr : 69);
length = ((length <= 70 - addr) ? length : 70 - addr);
sd3068_read_reg(0x2C + addr, data_buf, length);
return 0;
}
int sd3068_read_data_dma(uint8_t addr, uint8_t *data_buf, uint8_t length)
{
addr = ((addr <= 69) ? addr : 69);
length = length <= 70 - addr ? length : 70 - addr;
sd3068_read_reg_dma(0x2C + addr, data_buf, length);
return 0;
}
int sd3068_set_time(struct time_t time)
{
uint8_t data[7] = {0};
data[0] = hex2bcd(time.sec);
data[1] = hex2bcd(time.min);
data[2] = hex2bcd(time.hour) | 0x80;
data[3] = hex2bcd(5);
data[4] = hex2bcd(time.day);
data[5] = hex2bcd(time.month);
data[6] = hex2bcd(time.year);
sd3068_write_reg(0x00, data, 7);
return 0;
}
int sd3068_set_time_dma(struct time_t time)
{
uint8_t data[7] = {0};
data[0] = hex2bcd(time.sec);
data[1] = hex2bcd(time.min);
data[2] = hex2bcd(time.hour) | 0x80;
data[3] = hex2bcd(5);
data[4] = hex2bcd(time.day);
data[5] = hex2bcd(time.month);
data[6] = hex2bcd(time.year);
sd3068_write_reg_dma(0x00, data, 7);
return 0;
}
int sd3068_get_time(struct time_t *time)
{
uint8_t data[7] = {0};
sd3068_read_reg(0x00, data, 7);
time->sec = bcd2hex(data[0]);
time->min = bcd2hex(data[1]);
time->hour = bcd2hex(data[2] & 0x7F);
time->day = bcd2hex(data[4]);
time->month = bcd2hex(data[5]);
time->year = bcd2hex(data[6]);
return 0;
}
int sd3068_get_time_dma(struct time_t *time)
{
uint8_t data[7] = {0};
sd3068_read_reg_dma(0x00, data, 7);
time->sec = bcd2hex(data[0]);
time->min = bcd2hex(data[1]);
time->hour = bcd2hex(data[2] & 0x7F);
time->day = bcd2hex(data[4]);
time->month = bcd2hex(data[5]);
time->year = bcd2hex(data[6]);
return 0;
}