Files
kunlun/dtest/dtest3/mac_phy/rf_mac/mac_zc_dtest.c
2024-09-28 14:24:04 +08:00

475 lines
14 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_task.h"
#include "os_utils.h"
/* common includes */
#include "iot_io.h"
#include "iot_dbglog_api.h"
#include "iot_config.h"
#include "iot_errno_api.h"
/* driver includes */
#include "apb_dma.h"
#include "dma_hw.h"
/* debug includes*/
#include "dbg_io.h"
/* driver includes */
#include "cpu.h"
#include "iot_gpio_api.h"
#include "hw_reg_api.h"
#include "ahb.h"
#include "iot_irq.h"
#include "iot_bitops_api.h"
#include "iot_utils_api.h"
#include "mac_sys_reg.h"
#include "mac_int.h"
/* check mac zc ntb fifo enable */
#define DTEST_MAC_ZC_CHK_NTB_FIFO_ENA 1
/* check mac zc local fifo enable */
#define DTEST_MAC_ZC_CHK_LOCAL_FIFO_ENA 1
/* 0: poll, 1: interrupt */
#define DTSET_MAC_ZC_CHK_IS_INTR 1
/* mac zc hw cap id */
#define DTEST_MAC_ZC_CAP0 0
#define DTEST_MAC_ZC_CAP1 1
#define DTEST_MAC_ZC_CAP2 2
#define DTEST_MAC_ZC_CAP3 3
#define DTEST_MAC_ZC_CAP4 4
#define DTEST_MAC_ZC_CAP5 5
#define DTEST_MAC_ZC_CAP_CNT 6
/* cap hw fifo depth */
#define DTEST_MAC_ZC_HW_FIFO_CNT 8
/* cap latch ntb/local value wait cnt, uint: 75MHZ */
#define DTEST_MAC_ZC_SOLID_HIGH_NUM 200
#define DTEST_MAC_ZC_SOLID_LOW_NUM 200
/* mac zc period jitter max, same as KL1 */
#define DTEST_MAC_ZC_PERIOD_JITTER_NTB 12500
/* 50HZ period cap */
#define DTEST_MAC_ZC_PERIOD_GAP_NTB 500000 /* 20ms */
typedef struct _dtest_mac_zc_cap_info {
uint32_t isr_entry_cnt;
uint32_t isr_entry_backup;
uint32_t ntb_ts;
uint32_t local_ts;
} dtest_mac_zc_cap_info_t;
/* global */
os_task_h dtest_mac_zc_task_h;
iot_irq_t dtest_mac_isr_h_ext3;
dtest_mac_zc_cap_info_t g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP_CNT] = {0};
void dtest_mac_zc_sw_loop_delay(uint32_t delay)
{
uint32_t cnt = 0;
while(cnt++ < (delay * 100 * 1000)) {
__asm volatile ("nop\n");
}
}
void dtest_mac_zc_hw_cap_enable(uint8_t cap_id, uint8_t is_ena)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_CTRL_ADDR - CFG_ZC0_CAP_CTRL_ADDR)
* cap_id) + CFG_ZC0_CAP_CTRL_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
REG_FIELD_SET(CFG_ZC0_CAP_ENABLE, tmp, !!is_ena);
RGF_MAC_WRITE_REG(reg_addr, tmp);
}
void dtest_mac_zc_hw_cap_intr_num_set(uint8_t cap_id, uint8_t num)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_CTRL_ADDR - CFG_ZC0_CAP_CTRL_ADDR)
* cap_id) + CFG_ZC0_CAP_CTRL_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
REG_FIELD_SET(CFG_ZC0_CAP_NUM, tmp, num);
RGF_MAC_WRITE_REG(reg_addr, tmp);
}
void dtest_mac_zc_hw_cap_sample_num_set(uint8_t cap_id, uint8_t num)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_CTRL_ADDR - CFG_ZC0_CAP_CTRL_ADDR)
* cap_id) + CFG_ZC0_CAP_CTRL_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
REG_FIELD_SET(CFG_ZC0_CAP_INTERVAL, tmp, num);
RGF_MAC_WRITE_REG(reg_addr, tmp);
}
/* in_sel: 0 - default, stability start point;
* 1 - not use. stability start point + SOLID_TIME
*/
void dtest_mac_zc_hw_in_sel_set(uint8_t cap_id, uint8_t in_sel)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_CTRL_ADDR - CFG_ZC0_CAP_CTRL_ADDR)
* cap_id) + CFG_ZC0_CAP_CTRL_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
REG_FIELD_SET(CFG_ZC0_IN_SEL, tmp, !!in_sel);
RGF_MAC_WRITE_REG(reg_addr, tmp);
}
void dtest_mac_zc_hw_cap_edge_set(uint8_t cap_id, uint8_t is_fall_edge)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_CTRL_ADDR - CFG_ZC0_CAP_CTRL_ADDR)
* cap_id) + CFG_ZC0_CAP_CTRL_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
if (is_fall_edge) {
REG_FIELD_SET(CFG_ZC0_EDGE_SEL, tmp, 1);
} else {
REG_FIELD_SET(CFG_ZC0_EDGE_SEL, tmp, 0);
}
RGF_MAC_WRITE_REG(reg_addr, tmp);
}
void dtest_mac_zc_hw_filter_set(uint8_t cap_id, uint16_t high, uint16_t low)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_SOLID_ADDR - CFG_ZC0_CAP_SOLID_ADDR)
* cap_id) + CFG_ZC0_CAP_SOLID_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
REG_FIELD_SET(CFG_ZC0_SOLID_HIGH_CNT, tmp, high);
REG_FIELD_SET(CFG_ZC0_SOLID_LOW_CNT, tmp, low);
RGF_MAC_WRITE_REG(reg_addr, tmp);
}
uint32_t dtest_mac_zc_hw_cap_data_num_get(uint32_t cap_id, uint8_t is_ntb)
{
uint32_t tmp;
uint32_t reg_addr;
reg_addr = ((CFG_ZC1_CAP_FIFO_STS_ADDR - CFG_ZC0_CAP_FIFO_STS_ADDR)
* cap_id) + CFG_ZC0_CAP_FIFO_STS_ADDR;
tmp = RGF_MAC_READ_REG(reg_addr);
if (is_ntb) {
return REG_FIELD_GET(CFG_RO_NTB_ZC0_FIFO_DATA_NUM, tmp);
} else {
return REG_FIELD_GET(CFG_RO_LOCAL_ZC0_FIFO_DATA_NUM, tmp);
}
}
uint32_t dtest_mac_zc_hw_cap_read(uint8_t cap_id, uint8_t is_ntb, uint8_t num,
uint32_t *buf)
{
uint32_t reg_addr;
uint32_t valid_num;
uint32_t idx;
if (is_ntb) {
reg_addr = ((CFG_NTB_ZC1_CAP_FIFO_DATA_ADDR
- CFG_NTB_ZC0_CAP_FIFO_DATA_ADDR) * cap_id) +
CFG_NTB_ZC0_CAP_FIFO_DATA_ADDR;
} else {
reg_addr = ((CFG_LOCAL_ZC1_CAP_FIFO_DATA_ADDR
- CFG_LOCAL_ZC0_CAP_FIFO_DATA_ADDR) * cap_id) +
CFG_LOCAL_ZC0_CAP_FIFO_DATA_ADDR;
}
valid_num = dtest_mac_zc_hw_cap_data_num_get(cap_id, is_ntb);
for (idx = 0; idx < min(valid_num, num); idx++) {
buf[idx] = RGF_MAC_READ_REG(reg_addr);;
}
//iot_printf("cap:%d num:%d-%d\n", cap_id, valid_num, num);
return idx;
}
uint32_t dtest_mac_zc_isr_status_get(void)
{
return RGF_MAC_READ_REG(CFG_MAC_INT_EXT_3_STS_ADDR);
}
void dtest_mac_zc_isr_clr(uint32_t status)
{
RGF_MAC_WRITE_REG(CFG_MAC_INT_EXT_3_CLR_ADDR, status);
}
void dtest_mac_zc_isr_enable(uint8_t bitmap)
{
uint32_t tmp;
tmp = ((1 << DTEST_MAC_ZC_CAP_CNT) - 1) & bitmap;
RGF_MAC_WRITE_REG(CFG_MAC_INT_EXT_3_ENA_ADDR, tmp);
}
void dtest_mac_zc_isr_start(void)
{
iot_interrupt_unmask(dtest_mac_isr_h_ext3);
}
void dtest_mac_zc_isr_stop(void)
{
iot_interrupt_mask(dtest_mac_isr_h_ext3);
}
uint32_t dtest_mac_zc_isr_handle(uint32_t vector, iot_addrword_t data)
{
(void)vector;
(void)data;
uint32_t intr_status;
intr_status = dtest_mac_zc_isr_status_get();
dtest_mac_zc_isr_clr(intr_status);
if (intr_status & (1 << DTEST_MAC_ZC_CAP0)) {
g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP0].isr_entry_cnt++;
}
if (intr_status & (1 << DTEST_MAC_ZC_CAP1)) {
g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP1].isr_entry_cnt++;
}
if (intr_status & (1 << DTEST_MAC_ZC_CAP2)) {
g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP2].isr_entry_cnt++;
}
if (intr_status & (1 << DTEST_MAC_ZC_CAP3)) {
g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP3].isr_entry_cnt++;
}
if (intr_status & (1 << DTEST_MAC_ZC_CAP4)) {
g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP4].isr_entry_cnt++;
}
if (intr_status & (1 << DTEST_MAC_ZC_CAP5)) {
g_dtest_mac_zc_info[DTEST_MAC_ZC_CAP5].isr_entry_cnt++;
}
return 0;
}
void dtest_mac_zc_isr_init(void)
{
/* disable mac zc interrupt */
dtest_mac_zc_isr_enable(0);
/* clear all interrupt */
dtest_mac_zc_isr_clr(0xFFFFFFFF);
dtest_mac_isr_h_ext3 = iot_interrupt_create(HAL_VECTOR_MAC_3,
HAL_INTR_PRI_7, (iot_addrword_t)NULL, dtest_mac_zc_isr_handle);
iot_interrupt_set_cpu(dtest_mac_isr_h_ext3, HAL_INTR_CPU_0);
iot_interrupt_attach(dtest_mac_isr_h_ext3);
/* enable mac zc interrupt */
dtest_mac_zc_isr_enable((1 << 6) - 1);
}
void dtest_mac_zc_hw_init(void)
{
uint32_t id;
ahb_mac_enable();
ahb_mac_reg_enable();
ahb_mac_reset();
ahb_mac_reg_reset();
/* disable all mac zc cap */
for (id = 0; id < DTEST_MAC_ZC_CAP_CNT; id++) {
dtest_mac_zc_hw_cap_enable(id, 0);
}
dtest_mac_zc_isr_init();
dtest_mac_zc_isr_start();
/* gpio to mac zc signal map */ //TODO: chip need add
for (id = 0; id < DTEST_MAC_ZC_CAP_CNT; id++) {
dtest_mac_zc_hw_filter_set(id, DTEST_MAC_ZC_SOLID_HIGH_NUM,
DTEST_MAC_ZC_SOLID_LOW_NUM);
dtest_mac_zc_hw_cap_intr_num_set(id, 1);
dtest_mac_zc_hw_cap_sample_num_set(id, 1);
dtest_mac_zc_hw_in_sel_set(id, 0);
dtest_mac_zc_hw_cap_edge_set(id, 0);
}
/* enable all mac zc cap */
for (id = 0; id < DTEST_MAC_ZC_CAP_CNT; id++) {
dtest_mac_zc_hw_cap_enable(id, 1);
}
iot_printf("%s\n", __FUNCTION__);
}
uint32_t dtest_mac_zc_entry(uint32_t loop)
{
uint8_t i, j;
uint8_t ret, error_cnt;
uint32_t run_cnt;
uint32_t ntb_cnt, local_cnt;
uint32_t ntb_data, local_data;
dtest_mac_zc_cap_info_t *cur_cap;
uint32_t period_buf[DTEST_MAC_ZC_HW_FIFO_CNT];
uint32_t start_ts, cur_ts;
iot_printf("dtest_mac_zc start....\n");
/* init mac zc */
dtest_mac_zc_hw_init();
ret = 0;
run_cnt = 0;
start_ts = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
for (;;) {
for (i = 0; i < DTEST_MAC_ZC_CAP_CNT; i++) {
cur_cap = &g_dtest_mac_zc_info[i];
#if DTSET_MAC_ZC_CHK_IS_INTR
if ((uint32_t)(cur_cap->isr_entry_cnt - cur_cap->isr_entry_backup)
< (DTEST_MAC_ZC_HW_FIFO_CNT >> 1)) {
cur_ts = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
if ((uint32_t)(cur_ts - start_ts) > (5 * 1000 * 1000 * 25)) {
iot_printf("[WARN]long time not interrupt\n");
ret = 1;
goto out;
}
continue;
}
start_ts = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
#endif
iot_printf("cap:%d isr_cnt %u -> %u\n",
i, cur_cap->isr_entry_backup, cur_cap->isr_entry_cnt);
cur_cap->isr_entry_backup = cur_cap->isr_entry_cnt;
#if DTEST_MAC_ZC_CHK_NTB_FIFO_ENA
/* get ntb cap data */
ntb_cnt = dtest_mac_zc_hw_cap_data_num_get(i, 1);
if (ntb_cnt) {
iot_printf("ntb_cnt=%d: ", ntb_cnt);
for (j = 0; j < ntb_cnt; j++) {
dtest_mac_zc_hw_cap_read(i, 1, 1, &ntb_data);
period_buf[j] = (uint32_t)(ntb_data - cur_cap->ntb_ts);
iot_printf("%u, ", ntb_data);
cur_cap->ntb_ts = ntb_data;
}
iot_printf("\n");
error_cnt = 0;
iot_printf("ntb_period: ");
for (j = 0; j < ntb_cnt; j++) {
iot_printf("%u, ", period_buf[j]);
if (IOT_ABS((int32_t)(period_buf[j]
- DTEST_MAC_ZC_PERIOD_GAP_NTB))
> DTEST_MAC_ZC_PERIOD_JITTER_NTB) {
error_cnt++;
ret = 1;
}
}
iot_printf("\n");
if (error_cnt) {
iot_printf("[WARN]ntb_period_err %u\n", error_cnt);
}
}
#else
(void)ntb_cnt;
(void)ntb_data;
#endif
#if DTEST_MAC_ZC_CHK_LOCAL_FIFO_ENA
/* get local cap data */
local_cnt = dtest_mac_zc_hw_cap_data_num_get(i, 0);
if (local_cnt) {
iot_printf("local_cnt=%d, ", local_cnt);
for (j = 0; j < local_cnt; j++) {
dtest_mac_zc_hw_cap_read(i, 0, 1, &local_data);
period_buf[j] = (uint32_t)(local_data - cur_cap->local_ts);
iot_printf("%u, ", local_data);
cur_cap->local_ts = local_data;
}
iot_printf("\n");
error_cnt = 0;
iot_printf("local_period: ");
for (j = 0; j < local_cnt; j++) {
iot_printf("%u, ", period_buf[j]);
if (IOT_ABS((int32_t)(period_buf[j]
- DTEST_MAC_ZC_PERIOD_GAP_NTB))
> DTEST_MAC_ZC_PERIOD_JITTER_NTB) {
error_cnt++;
ret = 1;
}
}
iot_printf("\n");
if (error_cnt) {
iot_printf("[WARN]local_period_err %u\n", error_cnt);
}
}
#else
(void)local_cnt;
(void)local_data;
#endif
#if (DTEST_MAC_ZC_CHK_NTB_FIFO_ENA && DTEST_MAC_ZC_CHK_NTB_FIFO_ENA)
if (!ntb_cnt && !local_cnt) {
continue;
}
/* check ntb and local fifo count */
if (ntb_cnt != local_cnt) {
iot_printf("[WARN]cap%d ntb/local fifo cnt not match. "
"ntb_cnt:%u, local_cnt:%u\n",
i, ntb_cnt, local_cnt);
}
#endif
}
run_cnt++;
#if !DTSET_MAC_ZC_CHK_IS_INTR
dtest_mac_zc_sw_loop_delay(2);
#endif
if (run_cnt >= loop) {
goto out;
}
}
out:
iot_printf("dtest_mac_zc test %d\n", ret);
return ret;
}