Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

404
sdk/driver/crc/hg_crc.c Normal file
View File

@@ -0,0 +1,404 @@
/**
* @file hg_crc.c
* @author LeonLeeV
* @brief
* @version
* TXW80X; TXW81X; TXW82X
* @date 2023-08-02
*
* @copyright Copyright (c) 2023
*
*/
#include "typesdef.h"
#include "list.h"
#include "errno.h"
#include "dev.h"
#include "devid.h"
#include "osal/string.h"
#include "osal/semaphore.h"
#include "osal/mutex.h"
#include "osal/irq.h"
#include "dev/crc/hg_crc.h"
#include "hg_crc_hw.h"
struct hgcrc_config {
uint32 poly;
uint32 poly_bits;
uint32 init_val;
uint32 xor_out;
char ref_in;
char ref_out;
};
static const struct hgcrc_config tcpip_chksum = {
.init_val = 0x0,
.xor_out = 0x0,
.poly = 0x0,
.poly_bits = 0,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config crc5_usb = {
.init_val = 0x1f,
.xor_out = 0x1f,
.poly = 0x14,
.poly_bits = 5,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config crc7_mmc = {
.init_val = 0x0,
.xor_out = 0x0,
.poly = 0x48,
.poly_bits = 7,
.ref_in = 0,
.ref_out = 0,
};
static const struct hgcrc_config crc8_maxim = {
.init_val = 0x0,
.xor_out = 0x0,
.poly = 0x8C,
.poly_bits = 8,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config crc8 = {
.init_val = 0x0,
.xor_out = 0x0,
.poly = 0xE0,
.poly_bits = 8,
.ref_in = 0,
.ref_out = 0,
};
static const struct hgcrc_config crc16 = {
.init_val = 0x0,
.xor_out = 0x0,
.poly = 0xA001,
.poly_bits = 16,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config crc16_ccitt = {
.init_val = 0x0,
.xor_out = 0x0,
.poly = 0x8408,
.poly_bits = 16,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config crc16_modbus = {
.init_val = 0xFFFF,
.xor_out = 0x0,
.poly = 0xA001,
.poly_bits = 16,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config crc32_winrar = {
.init_val = 0xFFFFFFFF,
.xor_out = 0xFFFFFFFF,
.poly = 0xEDB88320,
.poly_bits = 32,
.ref_in = 1,
.ref_out = 1,
};
static const struct hgcrc_config *hgcrc_cfg[CRC_TYPE_MAX] = {
[CRC_TYPE_TCPIP_CHKSUM] = &tcpip_chksum,
[CRC_TYPE_CRC5_USB] = &crc5_usb,
[CRC_TYPE_CRC7_MMC] = &crc7_mmc,
[CRC_TYPE_CRC8_MAXIM] = &crc8_maxim,
[CRC_TYPE_CRC8] = &crc8,
[CRC_TYPE_CRC16] = &crc16,
[CRC_TYPE_CRC16_CCITT] = &crc16_ccitt,
[CRC_TYPE_CRC16_MODBUS] = &crc16_modbus,
[CRC_TYPE_CRC32_WINRAR] = &crc32_winrar,
};
static void hg_crc_irq_handler(void *data)
{
struct hg_crc *crc = (struct hg_crc *)data;
struct hg_crc_hw *hw = (struct hg_crc_hw *)crc->hw;
hw->CRC_KST = LL_CRC_KST_DMA_PENDING_CLR;
os_sema_up(&crc->done);
}
/**
* CRC len 512KB for TXW81x/TXW82X» 64KB for TXW80x
*/
static int32 hg_crc_calc_continue(struct crc_dev *crc, struct crc_dev_req *req, uint32 *crc_value)
{
int32 tmo = 2000;
int32 ret = 0;
struct hg_crc *dev = (struct hg_crc *)crc;
struct hg_crc_hw *hw = (struct hg_crc_hw *)dev->hw;
hw->CRC_INIT = hw->CRC_OUT ^ hw->CRC_INV;
/* kick */
#if defined(TXW80X)
hw->DMA_ADDR = (uint32)req->data & 0x00FFFFFF;
#else
hw->DMA_ADDR = (uint32)req->data;
#endif
hw->DMA_LEN = req->len;
ret = os_sema_down(&dev->done, tmo);
*crc_value = hw->CRC_OUT;
return ret > 0 ? RET_OK : RET_ERR;
}
int32 hg_crc5_usb_calc_nonos(struct crc_dev *crc, struct crc_dev_req *req, uint32 *crc_value, uint32 flags)
{
uint32 cfg_reg;
struct hg_crc *dev = (struct hg_crc *)crc;
struct hg_crc_hw *hw = (struct hg_crc_hw *)dev->hw;
hw->CRC_CFG &= ~ LL_CRC_CFG_INT_EN;
cfg_reg = LL_CRC_CFG_POLY_BITS(5) | LL_CRC_CFG_DMAWAIT_CLOCK(5);
cfg_reg |= LL_CRC_CFG_BIT_ORDER_RIGHT;
/* config */
hw->CRC_INIT = 0x1f;
hw->CRC_INV = 0x1f;
hw->CRC_POLY = 0x14;
hw->CRC_CFG = cfg_reg;
/* kick */
#if defined(TXW80X)
hw->DMA_ADDR = (uint32)req->data & 0x00FFFFFF;
#else
hw->DMA_ADDR = (uint32)req->data;
#endif
hw->DMA_LEN = req->len;
while(!(hw->CRC_STA & LL_CRC_STA_DMA_PENDING));
hw->CRC_KST = LL_CRC_KST_DMA_PENDING_CLR;
*crc_value = hw->CRC_OUT;
hw->CRC_CFG |= LL_CRC_CFG_INT_EN;
return 0;
}
int32 hg_crc8_calc_nonos(struct crc_dev *crc, struct crc_dev_req *req, uint32 *crc_value, uint32 flags)
{
uint32 cfg_reg;
struct hg_crc *dev = (struct hg_crc *)crc;
struct hg_crc_hw *hw = (struct hg_crc_hw *)dev->hw;
hw->CRC_CFG &= ~ LL_CRC_CFG_INT_EN;
cfg_reg = LL_CRC_CFG_POLY_BITS(8) | LL_CRC_CFG_DMAWAIT_CLOCK(5);
cfg_reg |= LL_CRC_CFG_BIT_ORDER_LEFT;
/* config */
hw->CRC_INIT = 0x0;
hw->CRC_INV = 0x0;
hw->CRC_POLY = 0xE0;
hw->CRC_CFG = cfg_reg;
/* kick */
#if defined(TXW80X)
hw->DMA_ADDR = (uint32)req->data & 0x00FFFFFF;
#else
hw->DMA_ADDR = (uint32)req->data;
#endif
hw->DMA_LEN = req->len;
while(!(hw->CRC_STA & LL_CRC_STA_DMA_PENDING));
hw->CRC_KST = LL_CRC_KST_DMA_PENDING_CLR;
*crc_value = hw->CRC_OUT;
hw->CRC_CFG |= LL_CRC_CFG_INT_EN;
return 0;
}
/**
* CRC len 512KB for TXW81x/TXW82X£» 64KB for TXW80x
*/
static int32 hg_crc_calc(struct crc_dev *crc, struct crc_dev_req *req, uint32 *crc_value, uint32 flags)
{
int32 ret = 0;
uint32 cfg_reg = 0;
struct hg_crc *dev = (struct hg_crc *)crc;
struct hg_crc_hw *hw = (struct hg_crc_hw *)dev->hw;
const struct hgcrc_config *p_cfg;
if (req == NULL || req->data == NULL || req->len == 0 || req->type >= CRC_TYPE_MAX) {
os_printf(KERN_ERR"%s ARG err\r\n", __FUNCTION__);
return -EINVAL;
}
if ((CRC_TYPE_TCPIP_CHKSUM == req->type) && (req->len < 4)) {
os_printf(KERN_ERR"%s not support\r\n", __FUNCTION__);
return -ENOTSUP;
}
if ((dev->flags & BIT(HGCRC_FLAGS_SUSPEND))) {
os_printf(KERN_ERR"%s at suspend\r\n", __FUNCTION__);
return -ENOTSUP;
}
p_cfg = hgcrc_cfg[req->type];
if (p_cfg == NULL) {
os_printf(KERN_ERR"%s not support\r\n", __FUNCTION__);
return -ENOTSUP;
}
os_mutex_lock(&dev->lock, osWaitForever);
os_sema_eat(&dev->done);
sysctrl_crc_reset();
if (0 == p_cfg->poly_bits) {
cfg_reg = LL_CRC_CFG_INT_EN | LL_CRC_CFG_TCP_MODE_EN | LL_CRC_CFG_DMAWAIT_CLOCK(5);
} else {
cfg_reg = LL_CRC_CFG_INT_EN | LL_CRC_CFG_POLY_BITS(p_cfg->poly_bits) | LL_CRC_CFG_DMAWAIT_CLOCK(5);
if (p_cfg->ref_in) {
cfg_reg |= LL_CRC_CFG_BIT_ORDER_RIGHT;
} else {
cfg_reg |= LL_CRC_CFG_BIT_ORDER_LEFT;
}
}
/* config */
hw->CRC_INV = p_cfg->xor_out;
hw->CRC_INIT = p_cfg->init_val;
if (flags & CRC_DEV_FLAGS_CONTINUE_CALC) {
hw->CRC_INIT = p_cfg->xor_out ^ req->crc_last;
}
hw->CRC_POLY = p_cfg->poly;
hw->CRC_CFG = cfg_reg;
/* kick */
#ifdef PSRAM_HEAP
if (req->flag) {
;
} else if (CRC_TYPE_TCPIP_CHKSUM == req->type) {
sys_dcache_clean_range_unaligned((uint32_t *)req->data, req->len);
} else {
sys_dcache_clean_range((uint32_t *)req->data, req->len);
}
#endif
#if defined(TXW80X)
hw->DMA_ADDR = (uint32)req->data & 0x00FFFFFF;
#else
hw->DMA_ADDR = (uint32)req->data;
#endif
hw->DMA_LEN = req->len;
ret = os_sema_down(&dev->done, 2000);
if (!ret) {
os_printf(KERN_ERR"%s timeout\r\n", __FUNCTION__);
}
*crc_value = hw->CRC_OUT;
os_mutex_unlock(&dev->lock);
return ret > 0 ? RET_OK : RET_ERR;
}
void hg_crc_test_printf(struct crc_dev *crc)
{
uint8_t src[64];
for (int i = 0;i<64;i++)
src[i] = 99+i;
struct crc_dev_req req = {
.type = CRC_TYPE_CRC32_WINRAR,
.data = src,
.len = 64,
};
uint32 crc_val = 0;
hg_crc_calc(crc, &req, &crc_val, 0);
_os_printf("crc r: 0x%08x\r\n", crc_val);
if (crc_val != 0x81efdc25) {
_os_printf("crc lp err\r\n");
}
}
#ifdef CONFIG_SLEEP
//#define HGCRC_SLEEP_TEST(dev) hg_crc_test_printf(dev)
#define HGCRC_SLEEP_TEST(dev)
int32 hg_crc_suspend(struct dev_obj *dev)
{
int32 ret = 0;
struct hg_crc *crc = (struct hg_crc *)dev;
struct hg_crc_hw *hw = (struct hg_crc_hw *)crc->hw;
if ((crc->flags & BIT(HGCRC_FLAGS_SUSPEND))) {
return RET_OK;
}
HGCRC_SLEEP_TEST(dev);
ret = os_mutex_lock(&crc->lock, osWaitForever);
if (ret < 0) {
return ret;
}
irq_disable(crc->irq_num);
crc->flags |= BIT(HGCRC_FLAGS_SUSPEND);
/* register backup ?*/
sysctrl_crc_clk_close();
return RET_OK;
}
int32 hg_crc_resume(struct dev_obj *dev)
{
int32 ret = 0;
struct hg_crc *crc = (struct hg_crc *)dev;
struct hg_crc_hw *hw = (struct hg_crc_hw *)crc->hw;
if ((crc->flags & BIT(HGCRC_FLAGS_SUSPEND))) {
ret = os_mutex_unlock(&crc->lock);
if (ret < 0) {
return ret;
}
sysctrl_crc_clk_open();
sysctrl_crc_reset();
/* register recovery ?*/
crc->flags &= ~ BIT(HGCRC_FLAGS_SUSPEND);
irq_enable(crc->irq_num);
HGCRC_SLEEP_TEST(dev);
}
return RET_OK;
}
#endif
static const struct crc_hal_ops crc_ops = {
.calc = hg_crc_calc,
#ifdef CONFIG_SLEEP
.ops.suspend = hg_crc_suspend,
.ops.resume = hg_crc_resume,
#endif
};
__init int32 hg_crc_attach(uint32 dev_id, struct hg_crc *crc)
{
struct hg_crc_hw *hw = (struct hg_crc_hw *)crc->hw;
crc->dev.dev.ops = (const struct devobj_ops *)&crc_ops;
crc->flags = 0;
os_mutex_init(&crc->lock);
os_sema_init(&crc->done, 0);
sysctrl_crc_clk_open();
sysctrl_crc_reset();
request_irq(crc->irq_num, hg_crc_irq_handler, crc);
hw->CRC_CFG |= LL_CRC_CFG_INT_EN;
irq_enable(crc->irq_num);
dev_register(dev_id, (struct dev_obj *)crc);
return RET_OK;
}

View File

@@ -0,0 +1,75 @@
#ifndef _HG_CRC_HW_H_
#define _HG_CRC_HW_H_
#ifdef __cplusplus
extern "C" {
#endif
enum hg_crc_flags {
HGCRC_FLAGS_SUSPEND = BIT(0),
HGCRC_FLAGS_HOLD = BIT(1),
};
/***** CRC_CFG Register *****/
/*! CRC interrupt enable
*/
#define LL_CRC_CFG_INT_EN (1UL << 0)
/*! CRC shift bit direction
*/
#define LL_CRC_CFG_BIT_ORDER_LEFT (1UL << 1)
#define LL_CRC_CFG_BIT_ORDER_RIGHT (0UL << 1)
/*! CRC POLY width: 5/7/8/16/32
*/
#define LL_CRC_CFG_POLY_BITS(n) (((n)&0x3F) << 8)
/*! CRC DMA data wait clock every time
*/
#define LL_CRC_CFG_DMAWAIT_CLOCK(n) (((n)&0x7) << 16)
/*! CRC TCP mode enable
*/
#define LL_CRC_CFG_TCP_MODE_EN (1UL << 24)
/***** CRC_KST Register *****/
/*! CRC pending clear
*/
#define LL_CRC_KST_DMA_PENDING_CLR (1UL << 0)
/***** CRC_STA Register *****/
/*! CRC pending
*/
#define LL_CRC_STA_DMA_PENDING (1UL << 0)
/***** CRC_INIT Register *****/
/***** CRC_INV Register *****/
/***** CRC_POLY Register *****/
/***** CRC_DMA_ADDR Register *****/
/***** CRC_DMA_LEN Register *****/
/***** CRC_CRC_OUT Register *****/
/**
* @brief CRC
*/
struct hg_crc_hw {
__IO uint32 CRC_CFG; // 0x0c
__IO uint32 CRC_INIT; // 0x04
__IO uint32 CRC_INV; // 0x08
__IO uint32 CRC_POLY; // 0x0c
__IO uint32 CRC_KST; // 0x10
__IO uint32 CRC_STA; // 0x14
uint32 RESERVED0;
__IO uint32 DMA_ADDR; // 0x1c
__IO uint32 DMA_LEN; // 0x20
__IO uint32 CRC_OUT; // 0x24
} ;
#ifdef __cplusplus
}
#endif
#endif /* _HG_CRC_H_ */