438 lines
8.6 KiB
C
438 lines
8.6 KiB
C
// Copyright 2020-2021 Beken
|
|
//
|
|
// 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 "hal.h"
|
|
#include "lin_hal.h"
|
|
#include <math.h>
|
|
|
|
#define DOUBLE_EPS (1e-15)
|
|
#define LIN_DIVISOR_IS_ZERO(x) do {\
|
|
if (fabs(x) < DOUBLE_EPS) {\
|
|
HAL_LOGE("the divisor is 0 \r\n");\
|
|
return BK_FAIL;\
|
|
}\
|
|
} while(0)
|
|
|
|
void lin_hal_set_soft_rst(uint32_t v)
|
|
{
|
|
lin_ll_set_global_ctrl_soft_rst(v);
|
|
}
|
|
void lin_hal_bypass_ckg(uint32_t v)
|
|
{
|
|
lin_ll_set_global_ctrl_bypass_cfg(v);
|
|
}
|
|
|
|
void lin_hal_master_cfg(lin_dev_t dev)
|
|
{
|
|
lin_ll_set_global_ctrl_master(dev);
|
|
}
|
|
|
|
uint32_t lin_hal_get_master(void)
|
|
{
|
|
return lin_ll_get_global_ctrl_master();
|
|
}
|
|
/* reg : data 0 - 7 */
|
|
void lin_hal_set_data_byte(uint32_t index, uint8_t v)
|
|
{
|
|
lin_ll_set_data_byte(index, v);
|
|
}
|
|
|
|
uint8_t lin_hal_get_data_byte(uint32_t index)
|
|
{
|
|
return lin_ll_get_data_byte(index);
|
|
}
|
|
|
|
/* reg :ctrl */
|
|
void lin_hal_set_ctrl_start_req(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_MASTER) {
|
|
lin_ll_set_ctrl_start_req(LIN_CTRL_START_REQ_MASK);
|
|
}
|
|
}
|
|
uint32_t lin_hal_get_ctrl_start_req(void)
|
|
{
|
|
return lin_ll_get_ctrl_start_req();
|
|
}
|
|
|
|
void lin_hal_set_ctrl_wakeup(void)
|
|
{
|
|
lin_ll_set_ctrl_wakeup(LIN_CTRL_WAKEUP_MASK);
|
|
}
|
|
|
|
uint32_t lin_hal_get_ctrl_wakeup(void)
|
|
{
|
|
return lin_ll_get_ctrl_wakeup();
|
|
}
|
|
|
|
void lin_hal_set_ctrl_reset_error(void)
|
|
{
|
|
lin_ll_set_ctrl_reset_error(LIN_CTRL_RESET_ERROR_MASK);
|
|
}
|
|
|
|
void lin_hal_set_ctrl_reset_int(void)
|
|
{
|
|
lin_ll_set_ctrl_reset_int(LIN_CTRL_RESET_INT_MASK);
|
|
}
|
|
|
|
void lin_hal_set_ctrl_data_ack(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
lin_ll_set_ctrl_data_ack(LIN_CTRL_DATA_ACK_MASK);
|
|
}
|
|
}
|
|
|
|
uint32_t lin_hal_get_ctrl_data_ack(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_ctrl_data_ack();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void lin_hal_set_ctrl_transmit(uint32_t v)
|
|
{
|
|
lin_ll_set_ctrl_transmit(v & LIN_CTRL_DATA_ACK_MASK);
|
|
}
|
|
|
|
uint32_t lin_hal_get_ctrl_transmit(void)
|
|
{
|
|
return lin_ll_get_ctrl_transmit();
|
|
}
|
|
|
|
void lin_hal_set_ctrl_sleep(void)
|
|
{
|
|
lin_ll_set_ctrl_sleep(LIN_CTRL_SLEEP_MASK);
|
|
}
|
|
|
|
uint32_t lin_hal_get_ctrl_sleep(void)
|
|
{
|
|
return lin_ll_get_ctrl_sleep();
|
|
}
|
|
|
|
void lin_hal_set_ctrl_stop(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
lin_ll_set_ctrl_stop(LIN_CTRL_STOP_MASK);
|
|
}
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_value(void)
|
|
{
|
|
return lin_ll_get_status_value();
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_complete(void)
|
|
{
|
|
return lin_ll_get_status_complete();
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_wake_up(void)
|
|
{
|
|
return lin_ll_get_status_wake_up();
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_error(void)
|
|
{
|
|
return lin_ll_get_status_error();
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_int(void)
|
|
{
|
|
return lin_ll_get_status_int();
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_data_req(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_status_data_req();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_aborted(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_status_aborted();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_bus_idle_timeout(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_status_bus_idle_timeout();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t lin_hal_get_status_lin_active(void)
|
|
{
|
|
return lin_ll_get_status_lin_active();
|
|
}
|
|
|
|
/* reg :error */
|
|
uint32_t lin_hal_get_error_value(void)
|
|
{
|
|
return lin_ll_get_err_value();
|
|
}
|
|
|
|
uint32_t lin_hal_get_error_bit(void)
|
|
{
|
|
return lin_ll_get_err_bit();
|
|
}
|
|
|
|
uint32_t lin_hal_get_error_chk(void)
|
|
{
|
|
return lin_ll_get_err_chk();
|
|
}
|
|
|
|
uint32_t lin_hal_get_error_timeout(void)
|
|
{
|
|
return lin_ll_get_err_timeout();
|
|
}
|
|
|
|
uint32_t lin_hal_get_error_parity(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_err_parity();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void lin_hal_set_prescl(uint32_t prescl)
|
|
{
|
|
uint32_t prescl1 = (prescl & LIN_BTCFG1_PRESCL1_MASK);
|
|
uint32_t prescl2 = ((prescl >> 2) & LIN_TCFG_PRESCL2_MASK);
|
|
|
|
lin_ll_set_btcfg1_prescl1(prescl1);
|
|
lin_ll_set_tcfg_prescl2(prescl2);
|
|
}
|
|
|
|
uint32_t lin_hal_get_prescl(void)
|
|
{
|
|
uint32_t prescl;
|
|
uint32_t prescl1;
|
|
uint32_t prescl2;
|
|
|
|
prescl1 = lin_ll_get_btcfg1_prescl1();
|
|
prescl2 = lin_ll_get_tcfg_prescl2();
|
|
prescl = (prescl1 & LIN_BTCFG1_PRESCL1_MASK) |
|
|
((prescl2 & LIN_TCFG_PRESCL2_MASK) << LIN_BTCFG1_PRESCL1_LEN);
|
|
|
|
return prescl;
|
|
}
|
|
|
|
|
|
void lin_hal_set_div(uint32_t div)
|
|
{
|
|
uint32_t div1 = (div & LIN_BTCFG0_BT_DIV1_MASK);
|
|
uint32_t div2 = ((div >> LIN_BTCFG0_BT_DIV1_LEN) & LIN_BTCFG1_BT_DIV2_MASK);
|
|
|
|
lin_ll_set_btcfg0_bt_div1(div1);
|
|
lin_ll_set_btcfg1_bt_div2(div2);
|
|
}
|
|
|
|
uint32_t lin_hal_get_div(void)
|
|
{
|
|
uint32_t div;
|
|
uint32_t div1;
|
|
uint32_t div2;
|
|
|
|
div1 = lin_ll_get_btcfg0_bt_div1();
|
|
div2 = lin_ll_get_btcfg1_bt_div2();
|
|
div = (div1 & LIN_BTCFG0_BT_DIV1_MASK) |
|
|
((div2 & LIN_BTCFG1_BT_DIV2_MASK) << LIN_BTCFG0_BT_DIV1_LEN);
|
|
|
|
return div;
|
|
}
|
|
|
|
void lin_hal_set_mul(uint32_t mul)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_MASTER) {
|
|
lin_ll_set_btcfg1_bt_mul(mul);
|
|
}
|
|
}
|
|
|
|
uint32_t lin_hal_get_mul(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_MASTER) {
|
|
return lin_ll_get_btcfg1_bt_mul();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void lin_hal_set_ident_value(uint32_t ident)
|
|
{
|
|
lin_ll_set_ident_value(ident);
|
|
}
|
|
|
|
uint32_t lin_hal_get_ident_value(void)
|
|
{
|
|
return lin_ll_get_ident_value();
|
|
}
|
|
|
|
void lin_hal_set_ident_id(uint32_t id)
|
|
{
|
|
lin_ll_set_ident_id(id);
|
|
}
|
|
|
|
uint32_t lin_hal_get_ident_id(void)
|
|
{
|
|
return lin_ll_get_ident_id();
|
|
}
|
|
|
|
void lin_hal_set_type_data_length(uint32_t data_length)
|
|
{
|
|
lin_ll_set_type_data_length(data_length);
|
|
}
|
|
|
|
uint32_t lin_hal_get_type_data_length(void)
|
|
{
|
|
return lin_ll_get_type_data_length();
|
|
}
|
|
|
|
void lin_hal_set_type_enh_check(uint32_t enh_check)
|
|
{
|
|
lin_ll_set_type_enh_check(enh_check);
|
|
}
|
|
|
|
uint32_t lin_hal_get_type_enh_check(void)
|
|
{
|
|
return lin_ll_get_type_enh_check();
|
|
}
|
|
|
|
void lin_hal_set_tcfg_wup_repeat_time(uint32_t time)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
lin_ll_set_tcfg_wup_repeat_time(time);
|
|
}
|
|
}
|
|
|
|
uint32_t lin_hal_get_tcfg_wup_repeat_time(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_tcfg_wup_repeat_time();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void lin_hal_set_tcfg_bus_inactivity_time(uint32_t time)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
lin_ll_set_tcfg_bus_inactivity_time(time);
|
|
}
|
|
}
|
|
|
|
uint32_t lin_hal_get_tcfg_bus_inactivity_time(void)
|
|
{
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
if (master == LIN_SLAVE) {
|
|
return lin_ll_get_tcfg_bus_inactivity_time();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void lin_hal_set_rate(double rate)
|
|
{
|
|
uint32_t mul;
|
|
uint32_t prescl;
|
|
uint32_t div;
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
|
|
if (rate < LIN_BAUD_RATE_MIN) {
|
|
rate = LIN_BAUD_RATE_MIN;
|
|
} else if (rate > LIN_BAUD_RATE_MAX) {
|
|
rate = LIN_BAUD_RATE_MAX;
|
|
}
|
|
|
|
if (master == LIN_MASTER) {
|
|
mul = floor(LIN_RATE_20KBIT / rate -1);
|
|
prescl = floor(log2(LIN_CLK_26M / ((mul + 1) * rate * 200) - 1));
|
|
div = floor(LIN_CLK_26M / (pow(2, prescl + 1) * (mul + 1) * rate));
|
|
|
|
lin_hal_set_mul(mul);
|
|
lin_hal_set_prescl(prescl);
|
|
lin_hal_set_div(div);
|
|
} else if (master == LIN_SLAVE) {
|
|
/* the configutation of the slave is only relate to the clock */
|
|
prescl = floor(log2(LIN_CLK_26M /( LIN_RATE_20KBIT* 200) -1));
|
|
div = floor(LIN_CLK_26M / (pow(2, prescl + 1) * LIN_RATE_20KBIT));
|
|
|
|
lin_hal_set_prescl( prescl);
|
|
lin_hal_set_div(div);
|
|
}
|
|
}
|
|
|
|
double lin_hal_get_rate(void)
|
|
{
|
|
double mul = lin_hal_get_mul();
|
|
uint32_t prescl = lin_hal_get_prescl();
|
|
double div = lin_hal_get_div();
|
|
uint32_t master = lin_ll_get_global_ctrl_master();
|
|
double rate = 0.0;
|
|
|
|
LIN_DIVISOR_IS_ZERO(div);
|
|
|
|
if (master == LIN_MASTER) {
|
|
rate = floor(LIN_CLK_26M/(pow(2, prescl + 1) * div * (mul + 1)));
|
|
}
|
|
|
|
return rate;
|
|
}
|
|
|
|
bk_err_t lin_hal_init(void)
|
|
{
|
|
lin_hal_set_soft_rst(0);
|
|
lin_hal_set_soft_rst(1);
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
bk_err_t lin_hal_deinit(void)
|
|
{
|
|
lin_hal_set_soft_rst(0);
|
|
|
|
return BK_OK;
|
|
}
|
|
|
|
#if (CONFIG_LIN_PM_CB_SUPPORT)
|
|
void lin_hal_backup(uint32_t *pm_backup)
|
|
{
|
|
lin_ll_backup(pm_backup);
|
|
}
|
|
|
|
void lin_hal_restore(uint32_t *pm_backup)
|
|
{
|
|
lin_ll_restore(pm_backup);
|
|
}
|
|
#endif
|