Files
plant_car/drivers/source/xtrg/sdrv_xtrg.c
2025-11-08 13:26:19 +08:00

889 lines
27 KiB
C

/**
* @file sdrv_xtrg.c
* @brief Semidrive XTRG driver source file.
*
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
* All rights reserved.
*/
#include <debug.h>
#include <param.h>
#include <string.h>
#include <types.h>
#include "sdrv_xtrg.h"
#include "irq.h"
/* Xtrg interrupt bit mask. */
#define SDRV_XTRG_TMUX7_DONE (1 << 23U)
#define SDRV_XTRG_TMUX6_DONE (1 << 22U)
#define SDRV_XTRG_TMUX5_DONE (1 << 21U)
#define SDRV_XTRG_TMUX4_DONE (1 << 20U)
#define SDRV_XTRG_TMUX3_DONE (1 << 19U)
#define SDRV_XTRG_TMUX2_DONE (1 << 18U)
#define SDRV_XTRG_TMUX1_DONE (1 << 17U)
#define SDRV_XTRG_TMUX0_DONE (1 << 16U)
#define SDRV_XTRG_FAULT_EVENT 1
/**
* @brief xTRG interrupt event structure.
*/
struct xtrg_intr_event {
uint32_t intr_mask;
sdrv_xtrg_irq_status_e event;
};
static const struct xtrg_intr_event xtrg_intr_events[] = {
{SDRV_XTRG_FAULT_EVENT, SDRV_FAULT_EVENT},
{SDRV_XTRG_TMUX0_DONE, SDRV_TMUX0_DONE_EVENT},
{SDRV_XTRG_TMUX1_DONE, SDRV_TMUX1_DONE_EVENT},
{SDRV_XTRG_TMUX2_DONE, SDRV_TMUX2_DONE_EVENT},
{SDRV_XTRG_TMUX3_DONE, SDRV_TMUX3_DONE_EVENT},
{SDRV_XTRG_TMUX4_DONE, SDRV_TMUX4_DONE_EVENT},
{SDRV_XTRG_TMUX5_DONE, SDRV_TMUX5_DONE_EVENT},
{SDRV_XTRG_TMUX6_DONE, SDRV_TMUX6_DONE_EVENT},
{SDRV_XTRG_TMUX7_DONE, SDRV_TMUX7_DONE_EVENT},
};
/* {S,C,T,P} values */
static const uint32_t sctp[] = {
[SDRV_XTRG_SWT_EVENT_SET] = 0x8,
[SDRV_XTRG_SWT_EVENT_CLEAR] = 0x4,
[SDRV_XTRG_SWT_EVENT_TRIGGER] = 0x2,
[SDRV_XTRG_SWT_EVENT_PULSE] = 0x1,
};
#if (CONFIG_E3L)
static sdrv_xtrg_sig_group_t sdrv_xtrg_sig_groups[] = {
[SDRV_XTRG_SWT_i_GROUP] =
{
.sig_nr = SWT_i_NR,
.sse_idx = 0,
.smon_idx = 0,
.syncmux_idx = 0,
},
[SDRV_XTRG_TRG_i_GROUP] =
{
.sig_nr = TRG_i_NR,
.sse_idx = 8,
.smux_idx = 54,
.smon_idx = 72,
.sync_dis_off = TRG_SYNC_DIS,
},
[SDRV_XTRG_SIG_i_GROUP] =
{
.sig_nr = SIG_i_NR,
.sse_idx = 12,
.smux_idx = 16,
.smon_idx = 34,
.sync_dis_off = SIG_SYNC_DIS,
},
[SDRV_XTRG_SYNC_i_GROUP] =
{
.sig_nr = SYNC_i_NR,
.sse_idx = 50,
.smon_idx = 24,
.syncmux_idx = 24,
.sync_dis_off = SYNC_SYNC_DIS,
},
[SDRV_XTRG_IO_i_GROUP] =
{
.sig_nr = IO_i_NR,
.sse_idx = 60,
.smux_idx = 58,
.smon_idx = 76,
.sync_dis_off = IO_SYNC_DIS,
},
[SDRV_XTRG_TID_i_GROUP] =
{
.sig_nr = TID_i_NR,
},
[SDRV_XTRG_SIG_o_GROUP] =
{
.sig_nr = SIG_o_NR,
.smon_idx = 10,
},
[SDRV_XTRG_IO_o_GROUP] =
{
.sig_nr = IO_o_NR,
.smon_idx = 50,
},
[SDRV_XTRG_SYNC_o_GROUP] =
{
.sig_nr = SYNC_o_NR,
.smon_idx = 0,
},
[SDRV_XTRG_SSIG_GROUP] =
{
.sig_nr = SSIG_NR,
.smux_idx = 0,
.smon_idx = 8,
.syncmux_idx = 8,
},
};
#else
static sdrv_xtrg_sig_group_t sdrv_xtrg_sig_groups[] = {
[SDRV_XTRG_SWT_i_GROUP] =
{
.sig_nr = SWT_i_NR,
.sse_idx = 0,
.smon_idx = 0,
.syncmux_idx = 0,
},
[SDRV_XTRG_TRG_i_GROUP] =
{
.sig_nr = TRG_i_NR,
.sse_idx = 8,
.smux_idx = 84,
.smon_idx = 112,
.sync_dis_off = TRG_SYNC_DIS,
},
[SDRV_XTRG_SIG_i_GROUP] =
{
.sig_nr = SIG_i_NR,
.sse_idx = 16,
.smux_idx = 16,
.smon_idx = 44,
.sync_dis_off = SIG_SYNC_DIS,
},
[SDRV_XTRG_SYNC_i_GROUP] =
{
.sig_nr = SYNC_i_NR,
.sse_idx = 84,
.smon_idx = 24,
.syncmux_idx = 24,
.sync_dis_off = SYNC_SYNC_DIS,
},
[SDRV_XTRG_IO_i_GROUP] =
{
.sig_nr = IO_i_NR,
.sse_idx = 104,
.smux_idx = 92,
.smon_idx = 120,
.sync_dis_off = IO_SYNC_DIS,
},
[SDRV_XTRG_TID_i_GROUP] =
{
.sig_nr = TID_i_NR,
},
[SDRV_XTRG_SIG_o_GROUP] =
{
.sig_nr = SIG_o_NR,
.smon_idx = 20,
},
[SDRV_XTRG_IO_o_GROUP] =
{
.sig_nr = IO_o_NR,
.smon_idx = 96,
},
[SDRV_XTRG_SYNC_o_GROUP] =
{
.sig_nr = SYNC_o_NR,
.smon_idx = 0,
},
[SDRV_XTRG_SSIG_GROUP] =
{
.sig_nr = SSIG_NR,
.smux_idx = 0,
.smon_idx = 8,
.syncmux_idx = 8,
},
};
#endif
/**
* @brief sdrv xtrg write reg.
*
* @param[in] base reg base
* @param[in] val reg val
* @param[in] reg reg offset
*/
static inline void sdrv_xtrg_writel(paddr_t base, uint32_t reg, uint32_t val)
{
writel(val, base + reg);
}
/**
* @brief sdrv xtrg read reg.
*
* @param[in] base reg base
* @param[in] reg reg offset
*/
static inline uint32_t sdrv_xtrg_readl(paddr_t base, uint32_t reg)
{
return readl(base + reg);
}
/**
* @brief sdrv xtrg modify reg.
*
* @param[in] base reg base
* @param[in] reg reg offset
* @param[in] start start bit
* @param[in] width width
* @param[in] val reg val
*/
static inline void sdrv_xtrg_modifyl(paddr_t base, uint32_t reg, uint32_t start,
uint32_t width, uint32_t val)
{
RMWREG32(base + reg, start, width, val);
}
/**
* @brief XTRG irp handler.
*
* @param[in] irq sdrv xtrg irq.
* @param[in] ctrl sdrv xtrg controller
*/
int sdrv_xtrg_irq_handler(uint32_t irq, void *ctrl)
{
ASSERT(ctrl != NULL);
sdrv_xtrg_t *irq_ctrl = (sdrv_xtrg_t *)ctrl;
ASSERT(irq_ctrl->base > 0U);
uint32_t status = sdrv_xtrg_readl(irq_ctrl->base, FUNC_INT_STA);
if (irq_ctrl->cb != NULL) {
for (uint8_t i = 0; i < ARRAY_SIZE(xtrg_intr_events); i++) {
if (status & xtrg_intr_events[i].intr_mask) {
irq_ctrl->cb(irq_ctrl, xtrg_intr_events[i].event,
irq_ctrl->para);
}
}
}
sdrv_xtrg_writel(irq_ctrl->base, FUNC_INT_STA, status);
return 0;
}
/**
* @brief Init XTRG.
*
* @param[in] ctrl sdrv XTRG controller.
*/
void sdrv_xtrg_init(sdrv_xtrg_t *ctrl, xtrg_callback_t callback, void *para)
{
ASSERT(ctrl != NULL);
ASSERT(ctrl->base > 0U);
ctrl->cb = callback;
ctrl->para = para;
if (ctrl->irq > 0U) {
irq_attach(ctrl->irq, sdrv_xtrg_irq_handler, ctrl);
irq_enable(ctrl->irq);
}
}
/**
* @brief Deinit XTRG.
*
* @param[in] ctrl sdrv XTRG controller.
*/
void sdrv_xtrg_deinit(sdrv_xtrg_t *ctrl)
{
ASSERT(ctrl != NULL);
if (ctrl->irq > 0) {
irq_disable(ctrl->irq);
irq_detach(ctrl->irq);
}
}
/**
* @brief sdrv xtrg int enable.
*
* @param[in] ctrl xtrg controller
* @param[in] int_id int id
*/
void sdrv_xtrg_int_enable(sdrv_xtrg_t *ctrl, sdrv_xtrg_irq_status_e int_id)
{
uint32_t sta_en, sig_en;
sta_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_STA_EN);
sta_en |= 1 << int_id;
sdrv_xtrg_writel(ctrl->base, FUNC_INT_STA_EN, sta_en);
sig_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_SIG_EN);
sig_en |= 1 << int_id;
sdrv_xtrg_writel(ctrl->base, FUNC_INT_SIG_EN, sig_en);
}
/**
* @brief sdrv xtrg int disable.
*
* @param[in] ctrl xtrg dev
* @param[in] int_id int id
*/
void sdrv_xtrg_int_disable(sdrv_xtrg_t *ctrl, sdrv_xtrg_irq_status_e int_id)
{
uint32_t sta_en, sig_en;
sta_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_STA_EN);
sta_en &= ~(1 << int_id);
sdrv_xtrg_writel(ctrl->base, FUNC_INT_STA_EN, sta_en);
sig_en = sdrv_xtrg_readl(ctrl->base, FUNC_INT_SIG_EN);
sig_en &= ~(1 << int_id);
sdrv_xtrg_writel(ctrl->base, FUNC_INT_SIG_EN, sig_en);
}
/**
* @brief Enable or disable input signal synchronization.
*
* SIG_i, TRG_i, SYNC_i and IO_i signals are synchronized to timer clock domain
* by default. This function enable or disable signal synchronizations.
*
* @param[in] ctrl xTRG controller.
* @param[in] cfg xTRG configuration.
* @param[in] enable Enable or disable synchronization.
*/
void sdrv_xtrg_sync_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg,
bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(cfg != NULL);
sdrv_xtrg_i_group_e group_id = XTRG_i_GROUP(cfg->sig);
sdrv_xtrg_sig_group_t *group = &sdrv_xtrg_sig_groups[group_id];
uint32_t i = XTRG_i_SIG(cfg->sig);
sdrv_xtrg_modifyl(ctrl->base, group->sync_dis_off + i / 32, i % 32, 1,
!enable);
}
/**
* @brief Configure I/O filters.
*
* @param[in] ctrl xTRG controller.
* @param[in] cfg The input signal to enable or disable debouncing
* @param[in] io_filter_cfg I/O filter configuration.
*/
void sdrv_xtrg_io_filter_config(
sdrv_xtrg_t *ctrl, const sdrv_xtrg_io_filter_config_t *io_filter_cfg,
bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(io_filter_cfg != NULL);
uint32_t val = 0;
val = ((io_filter_cfg->sampling_intvl - 1) << 12) |
((io_filter_cfg->neg_edge_intvl - 2) << 8) |
((io_filter_cfg->pos_edge_intvl - 2) << 4) |
(io_filter_cfg->edge << 1) | enable;
sdrv_xtrg_writel(ctrl->base, IO_FLAT(XTRG_i_SIG(io_filter_cfg->sig)), val);
}
/**
* @brief Config SWT (software trigger).
*
* @param[in] ctrl xTRG controller.
* @param[in] swt_cfg swt configuration.
*/
int sdrv_xtrg_swt_config(sdrv_xtrg_t *ctrl,
const sdrv_xtrg_swt_config_t *swt_cfg)
{
ASSERT(ctrl != NULL);
ASSERT(swt_cfg != NULL);
int ret = 0;
uint32_t cnt = 0;
sdrv_xtrg_modifyl(ctrl->base, SW_TRG_PULSE_WIDTH(XTRG_i_SIG(swt_cfg->swt)),
16 * (XTRG_i_SIG(swt_cfg->swt) % 2), 16,
swt_cfg->width & 0x0000FFFFul);
while (sdrv_xtrg_readl(ctrl->base, SW_TRG_CTRL) != 0 && (cnt < 200000)) {
cnt++;
}
if (cnt >= 200000) {
ret = -1;
} else {
sdrv_xtrg_modifyl(ctrl->base, SW_TRG_CTRL, 4 * XTRG_i_SIG(swt_cfg->swt),
4, sctp[swt_cfg->event]);
ret = 0;
}
return ret;
}
/**
* @brief Enable or disable SSE5.
*ctrl
* @param[in] ctrl xTRG controller.
* @param[in] sse5_cfg xTRG sse configuration.
* @param[in] enable Enable or disable sse5.
*/
void sdrv_xtrg_sse5_config(sdrv_xtrg_t *ctrl,
const sdrv_xtrg_sse5_config_t *sse5_cfg, bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(sse5_cfg != NULL);
uint32_t sel03 = 0, sel4 = 0;
uint32_t ctrl_reg = 0;
for (int i = 0; i < 5; i++) {
sdrv_xtrg_i_group_e group_id = XTRG_i_GROUP(sse5_cfg->in[i].sig);
uint32_t idx = XTRG_i_SIG(sse5_cfg->in[i].sig);
if (i < 4) {
sel03 |= (sdrv_xtrg_sig_groups[group_id].sse_idx + idx) << (i * 8);
} else {
sel4 = sdrv_xtrg_sig_groups[group_id].sse_idx + idx;
}
ctrl_reg |= (sse5_cfg->in[i].edge_detect << (1 + i)) |
(sse5_cfg->in[i].edge << (6 + 2 * i));
}
sdrv_xtrg_writel(ctrl->base, SSE_IN_0_3_SEL(sse5_cfg->ssm_sel), sel03);
sdrv_xtrg_writel(ctrl->base, SSE_IN_4_SEL(sse5_cfg->ssm_sel), sel4);
sdrv_xtrg_writel(ctrl->base, SSE_REG(sse5_cfg->ssm_sel),
sse5_cfg->synthesis_val);
sdrv_xtrg_modifyl(ctrl->base, SSE_CTRL(sse5_cfg->ssm_sel), 0, 16, ctrl_reg);
sdrv_xtrg_modifyl(ctrl->base, SSE_CTRL(sse5_cfg->ssm_sel), 0, 1,
(uint32_t)enable);
}
/**
* @brief Configure signal mux, muxing input signals to SIG_o or IO_o.
*
* The smux module muxes SSIG, TRG_i, SIG_i, and I/O inputs to SIG_o
* and I/O outputs.
*
* @param[in] ctrl xTRG controller.
* @param[in] cfg xTRG configuration.
*/
void sdrv_xtrg_smux_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg)
{
ASSERT(ctrl != NULL);
ASSERT(cfg != NULL);
if (SDRV_XTRG_SIG_o_GROUP == XTRG_i_GROUP(cfg->sig_o)) {
sdrv_xtrg_writel(
ctrl->base, SIG_O_SEL(XTRG_i_SIG(cfg->sig_o)),
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].smux_idx +
XTRG_i_SIG(cfg->sig_i));
} else if (SDRV_XTRG_IO_o_GROUP == XTRG_i_GROUP(cfg->sig_o)) {
sdrv_xtrg_writel(
ctrl->base, IO_O_SEL(XTRG_i_SIG(cfg->sig_o)),
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].smux_idx +
XTRG_i_SIG(cfg->sig_i));
sdrv_xtrg_modifyl(ctrl->base, IO_OUT_EN(XTRG_i_SIG(cfg->sig_o)),
XTRG_i_SIG(cfg->sig_o) % 32, 1, 1);
}
}
/**
* @brief Configure IO output, muxing SSIG_i,TRG_i,SIG_i,IO_i to IO_o.
*
* @param[in] ctrl xTRG controler.
* @param[in] cfg xTRG configuration.
* @param[in] enable Enable or disable io out.
*/
void sdrv_xtrg_io_out_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg,
bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(cfg != NULL);
sdrv_xtrg_writel(ctrl->base, IO_O_SEL(XTRG_i_SIG(cfg->sig_o)),
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].smux_idx +
XTRG_i_SIG(cfg->sig_i));
sdrv_xtrg_modifyl(ctrl->base, IO_OUT_EN(XTRG_i_SIG(cfg->sig_o)),
XTRG_i_SIG(cfg->sig_o) % 32, 1, (uint32_t)enable);
}
/**
* @brief Configure syncmux, muxing input sync signals to SYNC_o.
*
* The syncmux module muxes SWT_i, SSIG and SYNC_i inputs to SYNC_o outputs.
*
* @param[in] ctrl xTRG controller.
* @param[in] cfg xTRG configuration.
*/
void sdrv_xtrg_syncmux_config(sdrv_xtrg_t *ctrl, const sdrv_xtrg_config_t *cfg)
{
ASSERT(ctrl != NULL);
ASSERT(cfg != NULL);
sdrv_xtrg_writel(
ctrl->base, SYNC_O_SEL(XTRG_i_SIG(cfg->sig_o)),
sdrv_xtrg_sig_groups[XTRG_i_GROUP(cfg->sig_i)].syncmux_idx +
XTRG_i_SIG(cfg->sig_i));
}
/**
* @brief Configure syncmux, muxing input sync signals to SYNC_o.
*
* The syncmux module muxes SWT_i, SSIG and SYNC_i inputs to SYNC_o outputs.
*
* @param[in] ctrl xTRG controller.
* @param[in] tmux_drt_cfg xTRG tmux direct configuration.
*/
void sdrv_xtrg_tmux0_drt_config(sdrv_xtrg_t *ctrl,
const sdrv_xtrg_tmux_drt_config_t *tmux_drt_cfg)
{
ASSERT(ctrl != NULL);
ASSERT(tmux_drt_cfg != NULL);
uint32_t trg_sel, tid_sel;
uint32_t decode_sel[2] = {0};
/* Input order is TRG_i, then SSIG. */
if (SDRV_XTRG_TRG_i_GROUP == XTRG_i_GROUP(tmux_drt_cfg->trigger_sig))
trg_sel = XTRG_i_SIG(tmux_drt_cfg->trigger_sig);
else
trg_sel = TRG_i_NR + XTRG_i_SIG(tmux_drt_cfg->trigger_sig);
tid_sel = XTRG_i_SIG(tmux_drt_cfg->tid);
sdrv_xtrg_writel(ctrl->base, TMUX0_DRT_CTRL(tmux_drt_cfg->tmux0_drt_sel),
(trg_sel << 3) + tid_sel);
for (int i = 0; i < 8; i++) {
if (i < 4) {
decode_sel[0] |= tmux_drt_cfg->target_lut[i] << (i * 8);
} else {
decode_sel[1] |= tmux_drt_cfg->target_lut[i] << ((i - 4) * 8);
}
}
sdrv_xtrg_writel(ctrl->base,
TMUX0_DRT_DECODE_SEL(tmux_drt_cfg->tmux0_drt_sel, 1),
decode_sel[0]);
sdrv_xtrg_writel(ctrl->base,
TMUX0_DRT_DECODE_SEL(tmux_drt_cfg->tmux0_drt_sel, 2),
decode_sel[1]);
sdrv_xtrg_modifyl(ctrl->base, TMUX_DEC_EN, tmux_drt_cfg->tmux0_drt_sel, 1,
1); // TMUX_DEC_EN
}
/**
* @brief Configure the Trigger Mux (tmux) indrt modules..
*
* The tmux muxes TRG_i, SSIG signals to ADC and ACMP modules, with specified
* TID. There are 8 "drt" decoders, whose TID comes from TID_i, and 8
* "indrt" decoders, whose TID comes from xTRG internel TID pool.
*
* @param[in] ctrl xTRG controller.
* @param[in] tmux_indrt xTRG tmux indirect configuration.
*/
void sdrv_xtrg_tmux0_indrt_config(
sdrv_xtrg_t *ctrl, const sdrv_xtrg_tmux_indrt_config_t *tmux_indrt_cfg)
{
ASSERT(ctrl != NULL);
ASSERT(tmux_indrt_cfg != NULL);
uint32_t trg_sel;
uint32_t decode_sel[2] = {0};
/* Input order is TRG_i, then SSIG. */
if (SDRV_XTRG_TRG_i_GROUP == XTRG_i_GROUP(tmux_indrt_cfg->trigger_sig))
trg_sel = XTRG_i_SIG(tmux_indrt_cfg->trigger_sig);
else
trg_sel = TRG_i_NR + XTRG_i_SIG(tmux_indrt_cfg->trigger_sig);
sdrv_xtrg_writel(ctrl->base,
TMUX0_INDRT_CTRL(tmux_indrt_cfg->tmux0_indrt_sel),
(tmux_indrt_cfg->term_tid << 16) | (trg_sel << 3) |
tmux_indrt_cfg->term_val);
for (int i = 0; i < 8; i++) {
if (i < 4) {
decode_sel[0] |= tmux_indrt_cfg->target_lut[i] << (i * 8);
} else {
decode_sel[1] |= tmux_indrt_cfg->target_lut[i] << ((i - 4) * 8);
}
}
sdrv_xtrg_writel(ctrl->base,
TMUX0_INDRT_DECODE_SEL(tmux_indrt_cfg->tmux0_indrt_sel, 1),
decode_sel[0]);
sdrv_xtrg_writel(ctrl->base,
TMUX0_INDRT_DECODE_SEL(tmux_indrt_cfg->tmux0_indrt_sel, 2),
decode_sel[1]);
sdrv_xtrg_writel(ctrl->base,
TMUX0_INDRT_TID_POOL(tmux_indrt_cfg->tmux0_indrt_sel, 1),
tmux_indrt_cfg->tid_pool[0]);
sdrv_xtrg_writel(ctrl->base,
TMUX0_INDRT_TID_POOL(tmux_indrt_cfg->tmux0_indrt_sel, 2),
tmux_indrt_cfg->tid_pool[1]);
sdrv_xtrg_modifyl(ctrl->base, TMUX_DEC_EN,
tmux_indrt_cfg->tmux0_indrt_sel + 8, 1,
1); // TMUX_DEC_EN
}
/**
* @brief Configure SMON (Signal Monitor).
* The SMON monitors the input and output signal groups
* First level select 32 input signals and 32 output signals.
* Second level select inputs from output of 1st level
*
* @param[in] ctrl xTRG controller.
* @param[in] smon_cfg smon configuration.
* @param[in] enable Enable or disable smon.
*/
void sdrv_xtrg_smon_config(sdrv_xtrg_t *ctrl,
const sdrv_xtrg_smon_config_t *smon_cfg, bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(smon_cfg != NULL);
sdrv_xtrg_i_group_e sig_in_group = XTRG_i_GROUP(smon_cfg->sig_in_sel);
sdrv_xtrg_i_group_e sig_out_group = XTRG_i_GROUP(smon_cfg->sig_out_sel);
uint32_t sig_in_idx = sdrv_xtrg_sig_groups[sig_in_group].smon_idx +
XTRG_i_SIG(smon_cfg->sig_in_sel);
uint32_t sig_out_idx = sdrv_xtrg_sig_groups[sig_out_group].smon_idx +
XTRG_i_SIG(smon_cfg->sig_out_sel);
sdrv_xtrg_writel(ctrl->base, SMON_FIRST_MUX_SELECT(smon_cfg->smon_sel),
(sig_out_idx << 8) | sig_in_idx);
sdrv_xtrg_writel(ctrl->base, SMON_SECOND_MUX_SELECT(smon_cfg->smon_sel),
(smon_cfg->change_pol_in0 << 15) |
(smon_cfg->sig_input1_sel << 8) |
smon_cfg->sig_input0_sel);
sdrv_xtrg_modifyl(ctrl->base, SMON_EN, smon_cfg->smon_sel, 1,
(uint32_t)enable);
}
/**
* @brief Configure SWDT Pulse Check.(Signal Watch Dog Timer).
*
* @param[in] ctrl xTRG controller.
* @param[in] swdt_cfg swdt configuration.
* @param[in] enable Enable or disable swdt.
*/
void sdrv_xtrg_swdt_config(sdrv_xtrg_t *ctrl,
const sdrv_xtrg_swdt_config_t *swdt_cfg, bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(swdt_cfg != NULL);
ASSERT((SDRV_XTRG_SWDT_PULSE_CHECK == swdt_cfg->xtrg_swdt_check_mode) ||
(SDRV_XTRG_SWDT_EVENT_CHECK == swdt_cfg->xtrg_swdt_check_mode));
if (SDRV_XTRG_SWDT_PULSE_CHECK == swdt_cfg->xtrg_swdt_check_mode) {
sdrv_xtrg_writel(
ctrl->base,
SWDT_IN_SEL(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sig_sel);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_PULSE_CHECK(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
1, 1, swdt_cfg->xtrg_swdt_pulse_check_config.swdt_pulse_check_edge);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_PULSE_CHECK(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
2, 1, swdt_cfg->xtrg_swdt_pulse_check_config.swdt_pulse_check_mode);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_PULSE_CHECK_WINDOW(
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
16, 16,
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_max_check_window);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_PULSE_CHECK_WINDOW(
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
0, 16,
swdt_cfg->xtrg_swdt_pulse_check_config.swdt_min_check_window);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_PULSE_CHECK(swdt_cfg->xtrg_swdt_pulse_check_config.swdt_sel),
0, 1, (uint32_t)enable);
} else {
sdrv_xtrg_writel(
ctrl->base,
SWDT_IN_SEL(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
swdt_cfg->xtrg_swdt_event_check_config.swdt_sig_sel);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_EVENT_CHECK(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
16, 16,
swdt_cfg->xtrg_swdt_event_check_config.swdt_event_check_window);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_EVENT_CHECK(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
1, 3, swdt_cfg->xtrg_swdt_event_check_config.event_trg_mode);
sdrv_xtrg_modifyl(
ctrl->base,
SWDT_EVENT_CHECK(swdt_cfg->xtrg_swdt_event_check_config.swdt_sel),
0, 1, (uint32_t)enable);
}
}
/**
* @brief Enable or disable DMA0/1.
*
* @param[in] ctrl xTRG controller.
* @param[in] config xTRG dma configuration.
* @param[in] enable Enable or disable dma.
*/
void sdrv_xtrg_dma_config(sdrv_xtrg_t *ctrl,
const sdrv_xtrg_dma_config_t *config, bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(config != NULL);
ASSERT((SDRV_XTRG_DMA0 == config->dma_sel) ||
(SDRV_XTRG_DMA1 == config->dma_sel));
if (SDRV_XTRG_DMA0 == config->dma_sel) {
sdrv_xtrg_writel(ctrl->base, DMAC0_CTRL,
(config->ssm_sel << 2) | (config->ssig_mode << 1));
sdrv_xtrg_modifyl(ctrl->base, DMAC0_CTRL, 0, 1, (uint32_t)enable);
} else {
sdrv_xtrg_writel(ctrl->base, DMAC1_CTRL,
(config->ssm_sel << 2) | (config->ssig_mode << 1));
sdrv_xtrg_modifyl(ctrl->base, DMAC1_CTRL, 0, 1, (uint32_t)enable);
}
}
/**
* @brief Read tmux adc result.
*
* @param[in] ctrl xTRG controller.
* @param[in] tmux_id xTRG tmux index.
* @param[in] adc_id xTRG adc index.
*
* @return adc result
*/
uint32_t sdrv_xtrg_adc_rslt(sdrv_xtrg_t *ctrl, sdrv_xtrg_tmux_sel_e tmux_id,
sdrv_xtrg_adc_sel_e adc_id)
{
ASSERT(ctrl != NULL);
return sdrv_xtrg_readl(ctrl->base, TMUX_ADC_RSLT(adc_id, tmux_id));
}
/**
* @brief Read tmux acmp result.
*
* @param[in] ctrl xTRG controller.
* @param[in] tmux_id xTRG tmux index.
* @param[in] acmp_id xTRG acmp index.
*
* @return acmp result
*/
uint32_t sdrv_xtrg_acmp_rslt(sdrv_xtrg_t *ctrl, sdrv_xtrg_tmux_sel_e tmux_id,
sdrv_xtrg_acmp_sel_e acmp_id)
{
ASSERT(ctrl != NULL);
return sdrv_xtrg_readl(ctrl->base, TMUX_ACMP_RSLT(acmp_id, tmux_id));
}
/**
* @brief sdrv xtrg fault source enable.
*
* @param[in] xtrg dev base.
* @param[in] fault_id xtrg fault source id.
*/
void sdrv_xtrg_fault_source_config(sdrv_xtrg_t *ctrl, uint32_t fault_id,
bool enable)
{
ASSERT(ctrl != NULL);
sdrv_xtrg_modifyl(ctrl->base, FAULT_SOURCE_EN(fault_id), fault_id % 32, 1,
(uint32_t)enable);
}
/**
* @brief Smon cmp err config.
*
* @param[in] ctrl xTRG controller.
* @param[in] xtrg_smon_cmp_err_config Smon cmp err config.
* @param[in] enable Enable or disable err signal.
*/
void sdrv_xtrg_smon_cmp_err_config(
sdrv_xtrg_t *ctrl,
sdrv_xtrg_smon_cmp_err_config_t *xtrg_smon_cmp_err_config, bool enable)
{
ASSERT(ctrl != NULL);
ASSERT(xtrg_smon_cmp_err_config != NULL);
uint32_t sta_en, sig_en;
sta_en = sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_ERR_INT_STA_EN);
if (enable) {
sta_en |= (1 << xtrg_smon_cmp_err_config->smon_cmp_err);
if (SDRV_SMON_COR_ERROR == xtrg_smon_cmp_err_config->err_sel) {
sig_en =
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN);
sig_en |= (1 << xtrg_smon_cmp_err_config->smon_cmp_err);
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN,
sig_en);
} else if (SDRV_SMON_UNC_ERROR == xtrg_smon_cmp_err_config->err_sel) {
sig_en =
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN);
sig_en |= (1 << xtrg_smon_cmp_err_config->smon_cmp_err);
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN,
sig_en);
}
} else {
sta_en &= ~(1 << xtrg_smon_cmp_err_config->smon_cmp_err);
if (SDRV_SMON_COR_ERROR == xtrg_smon_cmp_err_config->err_sel) {
sig_en =
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN);
sig_en &= ~(1 << xtrg_smon_cmp_err_config->smon_cmp_err);
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_COR_ERR_INT_SIG_EN,
sig_en);
} else if (SDRV_SMON_UNC_ERROR == xtrg_smon_cmp_err_config->err_sel) {
sig_en =
sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN);
sig_en &= ~(1 << xtrg_smon_cmp_err_config->smon_cmp_err);
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_UNC_ERR_INT_SIG_EN,
sig_en);
}
}
sdrv_xtrg_writel(ctrl->base, FUNC_SMON_CMP_ERR_INT_STA_EN, sta_en);
}
/**
* @brief sdrv xtrg read fault status.
*
* @param[in] xtrg dev base.
*/
uint32_t sdrv_xtrg_read_smon_cmp_err_status(sdrv_xtrg_t *ctrl)
{
ASSERT(ctrl != NULL);
uint32_t reg_val = 0;
reg_val = sdrv_xtrg_readl(ctrl->base, FUNC_SMON_CMP_ERR_INT_STA);
return reg_val;
}
/**
* @brief sdrv set up timeout value from ADC
*
* @param[in] xtrg dev base.
*/
void sdrv_xtrg_tmux_done_monitor_cnt_config(sdrv_xtrg_t *ctrl, uint8_t timeOutValue)
{
ASSERT(ctrl != NULL);
sdrv_xtrg_writel(ctrl->base, TUMX_DONE_MONITOR_CNT, timeOutValue);
}