Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources
This commit is contained in:
1818
sdk/driver/adc/hgadc_v1.c
Normal file
1818
sdk/driver/adc/hgadc_v1.c
Normal file
File diff suppressed because it is too large
Load Diff
45
sdk/driver/adc/hgadc_v1_hw.h
Normal file
45
sdk/driver/adc/hgadc_v1_hw.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef _HGADC_V1_HW_H
|
||||
#define _HGADC_V1_HW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LL_ADKEY_SOTF_KICK(hw) (hw->ADC_CON_KICK |= BIT(0))
|
||||
|
||||
#define LL_ADKEY_GET_IRQ_EN_SAMPLE_DONE(hw) (hw->ADKEY_CON & BIT(20))
|
||||
|
||||
#define LL_ADKEY_GET_DONE_PENDING(hw) (hw->ADKEY_STA & BIT(0))
|
||||
|
||||
#define LL_ADKEY_CLEAR_DONE_PENDING(hw) (hw->ADKEY_STA = BIT(0))
|
||||
|
||||
#define LL_ADKEY_GET_DATA(hw) (hw->ADKEY_DATA & 0xFFF)
|
||||
|
||||
|
||||
/** @brief ADC register structure
|
||||
* @{
|
||||
*/
|
||||
struct hgadc_v1_hw {
|
||||
__IO uint32 ADC_ANA_CTRL0;
|
||||
__IO uint32 ADC_ANA_CTRL1;
|
||||
__IO uint32 ADC_CON_EN;
|
||||
__IO uint32 ADC_CON_FUN;
|
||||
__IO uint32 ADC_CON_SMP;
|
||||
__IO uint32 ADC_CON_SEL0;
|
||||
__IO uint32 ADC_CON_SEL1;
|
||||
__IO uint32 ADC_CON_KICK;
|
||||
__IO uint32 ADC_CON_CMP;
|
||||
__IO uint32 ADC_CON_STA;
|
||||
__IO uint32 ADC_DMA_STADR;
|
||||
__IO uint32 ADC_DMA_CNT;
|
||||
__IO uint32 ADC_CON_EXTEND0;
|
||||
__IO uint32 ADC_CON_EXTEND1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGADC_V0_HW_H */
|
||||
404
sdk/driver/crc/hg_crc.c
Normal file
404
sdk/driver/crc/hg_crc.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
75
sdk/driver/crc/hg_crc_hw.h
Normal file
75
sdk/driver/crc/hg_crc_hw.h
Normal 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_ */
|
||||
|
||||
|
||||
216
sdk/driver/dma/dw_dmac.c
Normal file
216
sdk/driver/dma/dw_dmac.c
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "errno.h"
|
||||
#include "dev.h"
|
||||
#include "string.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "hal/dma.h"
|
||||
#include "dev/dma/dw_dmac.h"
|
||||
#include "osal/string.h"
|
||||
|
||||
static void dw_dmac_irq_handler(void *data)
|
||||
{
|
||||
uint32 ch;
|
||||
struct hgdma_dw *dma = (struct hgdma_dw *)data;
|
||||
|
||||
for(ch=0; ch<DW_DMAC_MAX_DMAC_CHN; ch++) {
|
||||
if((dma->hw->MaskTfrL & BIT(ch)) && (dma->hw->RawTfrL & BIT(ch))) {
|
||||
dma->hw->ClearTfrL = BIT(ch);
|
||||
dma->state[ch] |= DW_DMAC_XFER_DONE(ch);
|
||||
if(dma->irq_hdl[ch]) {
|
||||
dma->irq_hdl[ch]((void *)dma, ch, DMA_IRQ_TYPE_DONE, dma->irq_data[ch]);
|
||||
}
|
||||
}
|
||||
if((dma->hw->MaskErrL & BIT(ch)) && (dma->hw->RawErrL & BIT(ch))) {
|
||||
dma->hw->ClearErrL = BIT(ch);
|
||||
dma->state[ch] |= DW_DMAC_XFER_ERR(ch);
|
||||
if(dma->irq_hdl[ch]) {
|
||||
dma->irq_hdl[ch]((void *)dma, ch, DMA_IRQ_TYPE_ERROR, dma->irq_data[ch]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32 dw_dmac_xfer(struct dma_device *dma, struct dma_xfer_data *data)
|
||||
{
|
||||
uint32 ch;
|
||||
uint32 flags;
|
||||
uint32 src_id = data->src_id;
|
||||
uint32 dest_id = data->dst_id;
|
||||
uint32 direct = data->dir;
|
||||
uint8 src_dir = (data->src_addr_mode == DMA_XFER_MODE_RECYCLE) ? DW_DMAC_ADDR_NO_CHANGE : DW_DMAC_ADDR_INC;
|
||||
uint8 dst_dir = (data->dst_addr_mode == DMA_XFER_MODE_RECYCLE) ? DW_DMAC_ADDR_NO_CHANGE : DW_DMAC_ADDR_INC;
|
||||
struct hgdma_dw *dev = (struct hgdma_dw *)dma;
|
||||
struct hgdma_dw_hw *hw = (struct hgdma_dw_hw *)dev->hw;
|
||||
|
||||
if(!dev->opened) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
/* get free channel */
|
||||
flags = disable_irq();
|
||||
for(ch=0; ch<DW_DMAC_MAX_DMAC_CHN; ch++) {
|
||||
if(!(dev->chn_used_flag & BIT(ch))) {
|
||||
dev->chn_used_flag |= BIT(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enable_irq(flags);
|
||||
|
||||
if(ch >= DW_DMAC_MAX_DMAC_CHN)
|
||||
return -EBUSY;
|
||||
|
||||
ASSERT(data->element_per_width < DMA_SLAVE_BUSWIDTH_8_BYTES);
|
||||
if(data->element_per_width >= DMA_SLAVE_BUSWIDTH_8_BYTES) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
hw->CH[ch].SARH = 0x0000;
|
||||
hw->CH[ch].DARH = 0x0000;
|
||||
hw->CH[ch].SARL = data->src;
|
||||
hw->CH[ch].DARL = data->dest;
|
||||
switch(direct) {
|
||||
case DMA_XFER_DIR_M2M:
|
||||
hw->CH[ch].CTLL = DW_DMAC_CTLL_SMS(1) | DW_DMAC_CTLL_DMS(1) |
|
||||
DW_DMAC_CTLL_FC(DW_DMAC_FC_D_M2M) |
|
||||
DW_DMAC_CTLL_SRC_DIR(src_dir) |
|
||||
DW_DMAC_CTLL_DST_DIR(dst_dir);
|
||||
/* Configure dma req channel */
|
||||
hw->CH[ch].CFGH = DW_DMAC_CFGH_DST_PER(0) |
|
||||
DW_DMAC_CFGH_SRC_PER(0) |
|
||||
DW_DMAC_CFGH_PROTCTL(1);
|
||||
break;
|
||||
case DMA_XFER_DIR_D2M:
|
||||
hw->CH[ch].CTLL = DW_DMAC_CTLL_SMS(0) | DW_DMAC_CTLL_DMS(1) |
|
||||
DW_DMAC_CTLL_FC(DW_DMAC_FC_D_P2M) |
|
||||
DW_DMAC_CTLL_SRC_DIR(src_dir) |
|
||||
DW_DMAC_CTLL_DST_DIR(dst_dir);
|
||||
/* Configure dma req channel */
|
||||
hw->CH[ch].CFGH = DW_DMAC_CFGH_DST_PER(0) |
|
||||
DW_DMAC_CFGH_SRC_PER(src_id) |
|
||||
DW_DMAC_CFGH_PROTCTL(1);
|
||||
break;
|
||||
case DMA_XFER_DIR_M2D:
|
||||
hw->CH[ch].CTLL = DW_DMAC_CTLL_SMS(1) | DW_DMAC_CTLL_DMS(0) |
|
||||
DW_DMAC_CTLL_FC(DW_DMAC_FC_D_M2P) |
|
||||
DW_DMAC_CTLL_SRC_DIR(src_dir) |
|
||||
DW_DMAC_CTLL_DST_DIR(dst_dir);
|
||||
/* Configure dma req channel */
|
||||
hw->CH[ch].CFGH = DW_DMAC_CFGH_DST_PER(dest_id) |
|
||||
DW_DMAC_CFGH_SRC_PER(0) |
|
||||
DW_DMAC_CFGH_PROTCTL(1);
|
||||
break;
|
||||
case DMA_XFER_DIR_D2D:
|
||||
hw->CH[ch].CTLL = DW_DMAC_CTLL_SMS(0) | DW_DMAC_CTLL_DMS(0) |
|
||||
DW_DMAC_CTLL_FC(DW_DMAC_FC_D_P2P) |
|
||||
DW_DMAC_CTLL_SRC_DIR(src_dir) |
|
||||
DW_DMAC_CTLL_DST_DIR(dst_dir);
|
||||
/* Configure dma req channel */
|
||||
hw->CH[ch].CFGH = DW_DMAC_CFGH_DST_PER(dest_id) |
|
||||
DW_DMAC_CFGH_SRC_PER(src_id) |
|
||||
DW_DMAC_CFGH_PROTCTL(1);
|
||||
break;
|
||||
default:
|
||||
dev->chn_used_flag &= ~ BIT(ch);
|
||||
return RET_ERR;
|
||||
}
|
||||
/* Configure block size */
|
||||
hw->CH[ch].CTLH = data->element_num;
|
||||
|
||||
hw->CH[ch].CTLL |= DW_DMAC_CTLL_INT_EN |
|
||||
DW_DMAC_CTLL_SRC_MSIZE(DW_DMAC_MSIZE_1) |
|
||||
DW_DMAC_CTLL_DST_MSIZE(DW_DMAC_MSIZE_1) |
|
||||
DW_DMAC_CTLL_SRC_WIDTH(data->element_per_width) |
|
||||
DW_DMAC_CTLL_DST_WIDTH(data->element_per_width);
|
||||
/* AMBA burst length no limited. */
|
||||
hw->CH[ch].CFGL = DW_DMAC_CFGL_MAX_BURST(0);
|
||||
|
||||
dev->state[ch] = 0x0000;
|
||||
dev->irq_hdl[ch] = data->irq_hdl;
|
||||
dev->irq_data[ch] = data->irq_data;
|
||||
|
||||
//start xfer
|
||||
hw->ChEnRegL = DW_DMAC_WRITE_EN(ch);
|
||||
return ch;
|
||||
}
|
||||
|
||||
static int32 dw_dmac_get_status(struct dma_device *dma, uint32 chn)
|
||||
{
|
||||
struct hgdma_dw *dev = (struct hgdma_dw *)dma;
|
||||
|
||||
if(!dev->opened) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
if(dev->state[chn] & DW_DMAC_XFER_ERR(chn)) {
|
||||
return DMA_ERROR;
|
||||
} else if(dev->state[chn] & DW_DMAC_XFER_DONE(chn)) {
|
||||
return DMA_SUCCESS;
|
||||
} else {
|
||||
return DMA_IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 dw_dmac_stop(struct dma_device *dma, uint32 chn)
|
||||
{
|
||||
uint32 flags;
|
||||
|
||||
struct hgdma_dw *dev = (struct hgdma_dw *)dma;
|
||||
struct hgdma_dw_hw *p_dmac = (struct hgdma_dw_hw *)dev->hw;
|
||||
|
||||
flags = disable_irq();
|
||||
if(dev->chn_used_flag & BIT(chn)) {
|
||||
p_dmac->ChEnRegL = DW_DMAC_WRITE_DIS(chn);
|
||||
dev->chn_used_flag &= ~ BIT(chn);
|
||||
}
|
||||
enable_irq(flags);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const struct dma_hal_ops dw_ops = {
|
||||
.xfer = dw_dmac_xfer,
|
||||
.get_status = dw_dmac_get_status,
|
||||
.stop = dw_dmac_stop,
|
||||
};
|
||||
|
||||
__init int32 dw_dmac_attach(uint32 dev_id, struct hgdma_dw *dmac)
|
||||
{
|
||||
uint32 ch;
|
||||
|
||||
dmac->opened = 1;
|
||||
dmac->dev.dev.ops = (const struct devobj_ops *)&dw_ops;
|
||||
|
||||
for(ch=0; ch<DW_DMAC_MAX_DMAC_CHN; ch++) {
|
||||
dmac->irq_hdl[ch] = NULL;
|
||||
dmac->irq_data[ch] = 0;
|
||||
dmac->state[ch] = 0;
|
||||
}
|
||||
|
||||
dmac->hw->ChEnRegL = 0xFF00;
|
||||
dmac->hw->DmaCfgRegL = 0x0000;
|
||||
|
||||
/* reset dmac */
|
||||
dmac->hw->ClearBlockL = DW_DMAC_MAX_DMAC_CHN_MASK;
|
||||
dmac->hw->ClearDstTranL = DW_DMAC_MAX_DMAC_CHN_MASK;
|
||||
dmac->hw->ClearErrL = DW_DMAC_MAX_DMAC_CHN_MASK;
|
||||
dmac->hw->ClearSrcTranL = DW_DMAC_MAX_DMAC_CHN_MASK;
|
||||
dmac->hw->ClearTfrL = DW_DMAC_MAX_DMAC_CHN_MASK;
|
||||
|
||||
/* disable mask */
|
||||
dmac->hw->MaskErrL = 0xFFFF;
|
||||
dmac->hw->MaskTfrL = 0xFFFF;
|
||||
dmac->hw->MaskBlockL = 0xFF00;
|
||||
dmac->hw->MaskDstTranL = 0xFF00;
|
||||
dmac->hw->MaskSrcTranL = 0xFF00;
|
||||
|
||||
/* enable DMAC */
|
||||
dmac->hw->DmaCfgRegL = DW_DMAC_CFG_DMA_EN;
|
||||
|
||||
irq_enable(dmac->irq_num);
|
||||
request_irq(dmac->irq_num, dw_dmac_irq_handler, dmac);
|
||||
dev_register(dev_id, (struct dev_obj *)dmac);
|
||||
return RET_OK;
|
||||
}
|
||||
434
sdk/driver/dma/hg_m2m_dma.c
Normal file
434
sdk/driver/dma/hg_m2m_dma.c
Normal file
@@ -0,0 +1,434 @@
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "errno.h"
|
||||
#include "dev.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/string.h"
|
||||
#include "hal/dma.h"
|
||||
#include "dev/dma/hg_m2m_dma.h"
|
||||
#include "osal/sleep.h"
|
||||
|
||||
#define DMA_LEN_THRESHOLD (2048)
|
||||
uint32_t in_disable_irq(void);
|
||||
|
||||
static void hg_m2m0_dma_irq_handler(void *data)
|
||||
{
|
||||
struct mem_dma_dev *dma = (struct mem_dma_dev *)data;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dma->hw;
|
||||
|
||||
hw->dma_ch[0].DMA_SAIE = 1;
|
||||
os_sema_up(&dma->done[0]);
|
||||
}
|
||||
|
||||
static void hg_m2m1_dma_irq_handler(void *data)
|
||||
{
|
||||
struct mem_dma_dev *dma = (struct mem_dma_dev *)data;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dma->hw;
|
||||
|
||||
hw->dma_ch[1].DMA_SAIE = 1;
|
||||
os_sema_up(&dma->done[1]);
|
||||
}
|
||||
|
||||
#ifdef TXW82X
|
||||
static void hg_m2m2_dma_irq_handler(void *data)
|
||||
{
|
||||
struct mem_dma_dev *dma = (struct mem_dma_dev *)data;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dma->hw;
|
||||
|
||||
hw->dma_ch[2].DMA_SAIE = 1;
|
||||
os_sema_up(&dma->done[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int32 hg_m2m_dma_get_free_ch(struct mem_dma_dev *dev, uint8 ch_fix)
|
||||
{
|
||||
int32 ch = (ch_fix >= HG_M2M_DMA_NUM) ? (HG_M2M_DMA_NUM-1) : ch_fix;
|
||||
uint32 flags = disable_irq();
|
||||
for (; ch>=0; ) {
|
||||
if (!(dev->busy_flag & BIT(ch))){
|
||||
dev->busy_flag |= BIT(ch);
|
||||
break;
|
||||
}
|
||||
if (ch_fix < HG_M2M_DMA_NUM) {
|
||||
ch = -1;
|
||||
break;
|
||||
} else {
|
||||
ch--;
|
||||
}
|
||||
}
|
||||
|
||||
enable_irq(flags);
|
||||
return ch;
|
||||
}
|
||||
|
||||
static inline void hg_m2m_dma_free_ch(struct mem_dma_dev *dev, int32 ch)
|
||||
{
|
||||
uint32 flags = disable_irq();
|
||||
dev->busy_flag &= ~ BIT(ch);
|
||||
enable_irq(flags);
|
||||
}
|
||||
|
||||
#define is_memset_same_val(n) ((((n) >> 0) & 0xff) == (((n) >> 8) & 0xff))
|
||||
static void hg_soft_memset(uint32 *dest, uint32 val, uint32 size)
|
||||
{
|
||||
uint32 i = 0;
|
||||
uint8 head_size = (uint32)dest % 4;
|
||||
uint8 tail_size = ((uint32)dest+size) % 4;
|
||||
uint32 c_size = ALIGN(size, 4) + ALIGN(head_size, 4);
|
||||
uint32 *p_dst = (uint32 *)((uint32)dest - head_size);
|
||||
uint8 *p_dst_bt = (uint8 *)dest;
|
||||
if (is_memset_same_val(val))
|
||||
{
|
||||
os_memset((void*)dest, (val & 0xff), size);
|
||||
} else {
|
||||
for (; i < c_size>>2; i++)
|
||||
*p_dst++ = val;
|
||||
for (i = head_size; i < (head_size << 1); i++)
|
||||
*p_dst_bt++ = val>>((i % 4)<<3);
|
||||
p_dst_bt = (uint8 *)((uint32)dest + size - tail_size);
|
||||
for (i = tail_size; i < (tail_size << 1); i++)
|
||||
*p_dst_bt++ = val>>((i % 4)<<3);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8 dma_element_size[4] = {1,2,4,8};
|
||||
static int32 hg_m2m_dma_xfer(struct dma_device *dma, struct dma_xfer_data *data)
|
||||
{
|
||||
int32 ch = -1;
|
||||
uint32 val = (data->src_addr_mode == DMA_XFER_MODE_RECYCLE) ? (*((uint32 *)data->src)) : (0);
|
||||
uint32 count = data->element_num * dma_element_size[data->element_per_width];
|
||||
static uint8 ch0_lock = 0;
|
||||
uint32 retry;
|
||||
uint32 addr_offset = 0;
|
||||
uint32 dma_cnt = 0;
|
||||
int32 ret = 0;
|
||||
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dev->hw;
|
||||
|
||||
retry = (__in_interrupt() || in_disable_irq()) ? 1 : (count >> (8+(2*dev->dma1_status)));
|
||||
if (!retry) retry = 1;
|
||||
|
||||
if (data->element_per_width >= DMA_SLAVE_BUSWIDTH_UNDEFINED) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* get free channel */
|
||||
for ( ; (!dev->suspend) && (retry--); ) {
|
||||
if (data->dir != DMA_XFER_DIR_M2M) {
|
||||
uint32 flags = disable_irq();
|
||||
ch = hg_m2m_dma_get_free_ch(dev, 0);
|
||||
if (0 == ch)
|
||||
ch0_lock = 1;
|
||||
enable_irq(flags);
|
||||
} else {
|
||||
ch = hg_m2m_dma_get_free_ch(dev, ch0_lock ? (HG_M2M_DMA_NUM - 1) : HG_M2M_DMA_NUM);
|
||||
}
|
||||
if (ch >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch < 0) {
|
||||
if (data->src_addr_mode == DMA_XFER_MODE_RECYCLE) {
|
||||
hg_soft_memset((void*)data->dest, val, count);
|
||||
} else if(data->src_addr_mode == DMA_XFER_MODE_INCREASE){
|
||||
os_memcpy((void*)data->dest, (void*)data->src, count);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
#ifdef TXW81X
|
||||
uint32 dst_addr = data->dest>>24;
|
||||
if (dst_addr == 0x38 || dst_addr == 0x08) {
|
||||
while(ll_sysctrl_dma2ahb_is_busy((ch) ? (DMA2AHB_BURST_CH_M2M1_WR) : (DMA2AHB_BURST_CH_M2M0_WR)));
|
||||
}
|
||||
#endif
|
||||
|
||||
//sysctrl_m2m_dma_reset();
|
||||
#if defined(TXW81X)
|
||||
hw->dma_ch[ch].DMA_CON &= HG_M2M_DMA_CON_ENDIAN_RES;
|
||||
hw->dma_ch[ch].DMA_ISIZE = 0;
|
||||
#elif defined(TXW82X)
|
||||
hw->dma_ch[ch].DMA_CON = 0x00;
|
||||
hw->dma_ch[ch].DMA_CON |= HG_M2M_DMA_CON_ENDIAN_SET(data->endian);
|
||||
#else
|
||||
hw->dma_ch[ch].DMA_CON = 0x00;
|
||||
#endif
|
||||
hw->dma_ch[ch].DMA_DATA = val;
|
||||
|
||||
while(count)
|
||||
{
|
||||
hw->dma_ch[ch].DMA_TADR = (uint32)data->dest + addr_offset;
|
||||
hw->dma_ch[ch].DMA_SADR = (uint32)data->src + addr_offset;
|
||||
dma_cnt = (count > (HG_M2M_DMA_MAX_LEN)) ? (HG_M2M_DMA_MAX_LEN) : (count);
|
||||
if ((!__in_interrupt()) && (!in_disable_irq()) && (dma_cnt > DMA_LEN_THRESHOLD)) {
|
||||
hw->dma_ch[ch].DMA_SAIE = 0x10001;
|
||||
os_sema_eat(&dev->done[ch]);
|
||||
} else {
|
||||
hw->dma_ch[ch].DMA_SAIE = 1;
|
||||
}
|
||||
hw->dma_ch[ch].DMA_DLEN = dma_cnt - 1;
|
||||
count -= dma_cnt;
|
||||
addr_offset += dma_cnt;
|
||||
|
||||
if (data->src_addr_mode == DMA_XFER_MODE_RECYCLE) {
|
||||
hw->dma_ch[ch].DMA_CON |= (HG_M2M_DMA_CON_MEMSET | HG_M2M_DMA_CON_DTE);
|
||||
} else if(data->src_addr_mode == DMA_XFER_MODE_INCREASE){
|
||||
hw->dma_ch[ch].DMA_CON |= (HG_M2M_DMA_CON_MEMCPY | HG_M2M_DMA_CON_DTE);
|
||||
}
|
||||
|
||||
if (hw->dma_ch[ch].DMA_SAIE & 0x10000) {
|
||||
ret = os_sema_down(&dev->done[ch], 50);
|
||||
if (!ret) {
|
||||
os_printf(KERN_ERR"hw_dma err: {%08x <--- %08x} len=%d\r\n", hw->dma_ch[ch].DMA_TADR, hw->dma_ch[ch].DMA_SADR, dma_cnt);
|
||||
}
|
||||
} else {
|
||||
while (hw->dma_ch[ch].DMA_CON & HG_M2M_DMA_CON_DTE) {
|
||||
}
|
||||
}
|
||||
}
|
||||
hw->dma_ch[ch].DMA_CON = 0x00;
|
||||
hg_m2m_dma_free_ch(dev, ch);
|
||||
if(ch && dev->dma1_mutex && !dev->dma1_status)
|
||||
{
|
||||
dev->dma1_status = true;
|
||||
hg_m2m_dma_get_free_ch(dev, ch);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
static int32 hg_m2m_dma_only_hw_xfer(struct dma_device *dma, struct dma_xfer_data *data)
|
||||
{
|
||||
int32 ch = -1;
|
||||
uint32 val = (data->src_addr_mode == DMA_XFER_MODE_RECYCLE) ? (*((uint32 *)data->src)) : (0);
|
||||
uint32 count = data->element_num * dma_element_size[data->element_per_width];
|
||||
static uint8 ch0_lock = 0;
|
||||
uint32 retry;
|
||||
uint32 addr_offset = 0;
|
||||
uint32 dma_cnt = 0;
|
||||
int32 ret = 0;
|
||||
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dev->hw;
|
||||
|
||||
retry = (__in_interrupt() || in_disable_irq()) ? 1 : (count >> (8+(2*dev->dma1_status)));
|
||||
if (!retry) retry = 1;
|
||||
|
||||
if (data->element_per_width >= DMA_SLAVE_BUSWIDTH_UNDEFINED) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* get free channel */
|
||||
for ( ; (!dev->suspend) && (retry); ) {
|
||||
if (data->dir != DMA_XFER_DIR_M2M) {
|
||||
uint32 flags = disable_irq();
|
||||
ch = hg_m2m_dma_get_free_ch(dev, 0);
|
||||
if (0 == ch)
|
||||
ch0_lock = 1;
|
||||
enable_irq(flags);
|
||||
} else {
|
||||
ch = hg_m2m_dma_get_free_ch(dev, ch0_lock ? (HG_M2M_DMA_NUM - 1) : HG_M2M_DMA_NUM);
|
||||
}
|
||||
if (ch >= 0) {
|
||||
break;
|
||||
}
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
|
||||
#ifdef TXW81X
|
||||
uint32 dst_addr = data->dest>>24;
|
||||
if (dst_addr == 0x38 || dst_addr == 0x08) {
|
||||
while(ll_sysctrl_dma2ahb_is_busy((ch) ? (DMA2AHB_BURST_CH_M2M1_WR) : (DMA2AHB_BURST_CH_M2M0_WR)));
|
||||
}
|
||||
#endif
|
||||
|
||||
//sysctrl_m2m_dma_reset();
|
||||
#if defined(TXW81X)
|
||||
hw->dma_ch[ch].DMA_CON &= HG_M2M_DMA_CON_ENDIAN_RES;
|
||||
hw->dma_ch[ch].DMA_ISIZE = 0;
|
||||
#elif defined(TXW82X)
|
||||
hw->dma_ch[ch].DMA_CON = 0x00;
|
||||
hw->dma_ch[ch].DMA_CON |= HG_M2M_DMA_CON_ENDIAN_SET(data->endian);
|
||||
#else
|
||||
hw->dma_ch[ch].DMA_CON = 0x00;
|
||||
#endif
|
||||
hw->dma_ch[ch].DMA_DATA = val;
|
||||
|
||||
while(count)
|
||||
{
|
||||
hw->dma_ch[ch].DMA_TADR = (uint32)data->dest + addr_offset;
|
||||
hw->dma_ch[ch].DMA_SADR = (uint32)data->src + addr_offset;
|
||||
dma_cnt = (count > (HG_M2M_DMA_MAX_LEN)) ? (HG_M2M_DMA_MAX_LEN) : (count);
|
||||
if ((!__in_interrupt()) && (!in_disable_irq()) && (dma_cnt > DMA_LEN_THRESHOLD)) {
|
||||
hw->dma_ch[ch].DMA_SAIE = 0x10001;
|
||||
os_sema_eat(&dev->done[ch]);
|
||||
} else {
|
||||
hw->dma_ch[ch].DMA_SAIE = 1;
|
||||
}
|
||||
hw->dma_ch[ch].DMA_DLEN = dma_cnt - 1;
|
||||
count -= dma_cnt;
|
||||
addr_offset += dma_cnt;
|
||||
|
||||
if (data->src_addr_mode == DMA_XFER_MODE_RECYCLE) {
|
||||
hw->dma_ch[ch].DMA_CON |= (HG_M2M_DMA_CON_MEMSET | HG_M2M_DMA_CON_DTE);
|
||||
} else if(data->src_addr_mode == DMA_XFER_MODE_INCREASE){
|
||||
hw->dma_ch[ch].DMA_CON |= (HG_M2M_DMA_CON_MEMCPY | HG_M2M_DMA_CON_DTE);
|
||||
}
|
||||
|
||||
if (hw->dma_ch[ch].DMA_SAIE & 0x10000) {
|
||||
ret = os_sema_down(&dev->done[ch], 50);
|
||||
if (!ret) {
|
||||
os_printf(KERN_ERR"hw_dma err: {%08x <--- %08x} len=%d\r\n", hw->dma_ch[ch].DMA_TADR, hw->dma_ch[ch].DMA_SADR, dma_cnt);
|
||||
}
|
||||
} else {
|
||||
while (hw->dma_ch[ch].DMA_CON & HG_M2M_DMA_CON_DTE) {
|
||||
}
|
||||
}
|
||||
}
|
||||
hw->dma_ch[ch].DMA_CON = 0x00;
|
||||
hg_m2m_dma_free_ch(dev, ch);
|
||||
if(ch && dev->dma1_mutex && !dev->dma1_status)
|
||||
{
|
||||
dev->dma1_status = true;
|
||||
hg_m2m_dma_get_free_ch(dev, ch);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
static int32 hg_m2m_dma_get_status(struct dma_device *dma, uint32 chn)
|
||||
{
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dev->hw;
|
||||
|
||||
if (hw->dma_ch[chn].DMA_CON & HG_M2M_DMA_CON_DTE) {
|
||||
return DMA_IN_PROGRESS;
|
||||
} else {
|
||||
return DMA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hg_m2m_dma_ioctl(struct dma_device *dma, uint32 cmd, int32 param1, int32 param2)
|
||||
{
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
#if (defined(TX81X) || defined(TXW82X))
|
||||
case DMA_IOCTL_CMD_ENDIAN:{
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
struct mem_dma_hw *hw = (struct mem_dma_hw *)dev->hw;
|
||||
for (int i = 0; i < HG_M2M_DMA_NUM; i++)
|
||||
hw->dma_ch[i].DMA_CON = ((hw->dma_ch[i].DMA_CON & (~HG_M2M_DMA_CON_ENDIAN_RES)) | HG_M2M_DMA_CON_ENDIAN_SET(param1));
|
||||
break;
|
||||
}
|
||||
|
||||
case DMA_IOCTL_CMD_CHECK_DMA1_STATUS:{
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
ret_val = dev->dma1_status;
|
||||
break;
|
||||
}
|
||||
|
||||
case DMA_IOCTL_CMD_DMA1_LOCK:{
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
int32 ch = hg_m2m_dma_get_free_ch(dev, 1);
|
||||
if(ch)
|
||||
{
|
||||
dev->dma1_status = true;
|
||||
}else{
|
||||
hg_m2m_dma_free_ch(dev, ch);
|
||||
dev->dma1_status = false;
|
||||
}
|
||||
dev->dma1_mutex = true;
|
||||
break;
|
||||
};
|
||||
|
||||
case DMA_IOCTL_CMD_DMA1_UNLOCK:{
|
||||
struct mem_dma_dev *dev = (struct mem_dma_dev *)dma;
|
||||
hg_m2m_dma_free_ch(dev, 1);
|
||||
dev->dma1_mutex = false;
|
||||
dev->dma1_status = false;
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
|
||||
default:
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SLEEP
|
||||
int32 hg_m2m_dma_suspend(struct dev_obj *dev)
|
||||
{
|
||||
struct mem_dma_dev *dma = (struct mem_dma_dev *)dev;
|
||||
|
||||
if (dma->suspend) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* force all dma busy */
|
||||
dma->suspend = 1;
|
||||
|
||||
for (int i = 0; i < HG_M2M_DMA_NUM; i++)
|
||||
while (0 != hg_m2m_dma_get_free_ch(dma, i)) { os_sleep_ms(1); }
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hg_m2m_dma_resume(struct dev_obj *dev)
|
||||
{
|
||||
struct mem_dma_dev *dma = (struct mem_dma_dev *)dev;
|
||||
|
||||
if (!dma->suspend) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
hg_m2m_dma_free_ch(dma, 0);
|
||||
hg_m2m_dma_free_ch(dma, 1);
|
||||
irq_enable(dma->irq_num);
|
||||
irq_enable(dma->irq_num+1);
|
||||
dma->suspend = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const struct dma_hal_ops m2m_ops = {
|
||||
.xfer = hg_m2m_dma_xfer,
|
||||
.only_hw_xfer = hg_m2m_dma_only_hw_xfer,
|
||||
.get_status = hg_m2m_dma_get_status,
|
||||
.ioctl = hg_m2m_dma_ioctl,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hg_m2m_dma_suspend,
|
||||
.ops.resume = hg_m2m_dma_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
__init int32 hg_m2m_dma_dev_attach(uint32 dev_id, struct mem_dma_dev *p_dma)
|
||||
{
|
||||
#ifdef TXW82X
|
||||
void *irq_handler[] = {hg_m2m0_dma_irq_handler, hg_m2m1_dma_irq_handler, hg_m2m2_dma_irq_handler};
|
||||
#else
|
||||
void *irq_handler[] = {hg_m2m0_dma_irq_handler, hg_m2m1_dma_irq_handler};
|
||||
#endif
|
||||
p_dma->dev.dev.ops = (const struct devobj_ops *)&m2m_ops;
|
||||
p_dma->busy_flag = 0;
|
||||
p_dma->suspend = 0;
|
||||
|
||||
for (uint8 i = 0; i < HG_M2M_DMA_NUM; i++)
|
||||
{
|
||||
os_sema_init(&p_dma->done[i], 0);
|
||||
p_dma->hw->dma_ch[i].DMA_CON = 0x00;
|
||||
p_dma->hw->dma_ch[i].DMA_SAIE = HG_M2M_DMA_SAIE_TCP_PENDING;
|
||||
irq_enable(p_dma->irq_num[i]);
|
||||
request_irq(p_dma->irq_num[i], irq_handler[i], p_dma);
|
||||
}
|
||||
|
||||
dev_register(dev_id, (struct dev_obj *)p_dma);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
1402
sdk/driver/gpio/hggpio_v4.c
Normal file
1402
sdk/driver/gpio/hggpio_v4.c
Normal file
File diff suppressed because it is too large
Load Diff
67
sdk/driver/gpio/hggpio_v4_hw.h
Normal file
67
sdk/driver/gpio/hggpio_v4_hw.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef _HGGPIO_V4_HW_H_
|
||||
#define _HGGPIO_V4_HW_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Switches for uncommon functions */
|
||||
#define HGGPIO_V4_DIR_ATOMIC_EN (1)
|
||||
#define HGGPIO_V4_DRIVER_STRENGTH_EN (1)
|
||||
#define HGGPIO_V4_DEBUNCE_EN (1)
|
||||
#define HGGPIO_V4_TOGGLE_EN (1)
|
||||
#define HGGPIO_V4_SET_ATOMIC_EN (1)
|
||||
#define HGGPIO_V4_ANALOG_EN (1)
|
||||
#define HGGPIO_V4_LOCK_EN (0)
|
||||
#define HGGPIO_V4_INPUT_LAG_EN (0)
|
||||
#define HGGPIO_V4_ADC_ANALOG_INPUT_EN (0)
|
||||
#define HGGPIO_V4_TK_ANALOG_INPUT_EN (0)
|
||||
|
||||
|
||||
/**
|
||||
* @breif huge-ic gpio register definition
|
||||
*/
|
||||
struct hggpio_v4_hw {
|
||||
__IO uint32_t MODE;
|
||||
__IO uint32_t OTYPE;
|
||||
__IO uint32_t OSPEEDL;
|
||||
__IO uint32_t OSPEEDH;
|
||||
__IO uint32_t PUPL;
|
||||
__IO uint32_t PUPH;
|
||||
__IO uint32_t PUDL;
|
||||
__IO uint32_t PUDH;
|
||||
__IO uint32_t IDAT;
|
||||
__IO uint32_t ODAT;
|
||||
__IO uint32_t BSR;
|
||||
__IO uint32_t RES0;
|
||||
__IO uint32_t AFRL;
|
||||
__IO uint32_t AFRH;
|
||||
__IO uint32_t TGL;
|
||||
__IO uint32_t IMK;
|
||||
__IO uint32_t HY;
|
||||
__IO uint32_t RES2;
|
||||
__IO uint32_t RES3;
|
||||
__IO uint32_t DEBEN;
|
||||
__IO uint32_t AIOEN;
|
||||
__IO uint32_t PND;
|
||||
__IO uint32_t PNDCLR;
|
||||
__IO uint32_t TRG0;
|
||||
__IO uint32_t RES4;
|
||||
__IO uint32_t RES5;
|
||||
__IO uint32_t RES6;
|
||||
__IO uint32_t RES7;
|
||||
__IO uint32_t IEEN;
|
||||
__IO uint32_t IOFUNCOUTCON0;
|
||||
__IO uint32_t IOFUNCOUTCON1;
|
||||
__IO uint32_t IOFUNCOUTCON2;
|
||||
__IO uint32_t IOFUNCOUTCON3;
|
||||
} ;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGGPIO_V4_HW_H_ */
|
||||
|
||||
1101
sdk/driver/i2c/hgi2c_v1.c
Normal file
1101
sdk/driver/i2c/hgi2c_v1.c
Normal file
File diff suppressed because it is too large
Load Diff
306
sdk/driver/i2c/hgi2c_v1_hw.h
Normal file
306
sdk/driver/i2c/hgi2c_v1_hw.h
Normal file
@@ -0,0 +1,306 @@
|
||||
#ifndef _HGI2C_V1_HW_H
|
||||
#define _HGI2C_V1_HW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup IIC MODULE REGISTER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/***** CON0(for IIC) Register *****/
|
||||
#define LL_IIC_CON0_SBC_IE(n) (((n)&0x01) << 30)
|
||||
|
||||
#define LL_IIC_CON0_SBC_EN(n) (((n)&0x01) << 29)
|
||||
|
||||
#define LL_IIC_CON0_ALERT_IE(n) (((n)&0x01) << 28)
|
||||
|
||||
#define LL_IIC_CON0_NOSTRETCH_EN(n) (((n)&0x01) << 27)
|
||||
|
||||
#define LL_IIC_CON0_SMBDEV_ADR_EN(n) (((n)&0x01) << 26)
|
||||
|
||||
#define LL_IIC_CON0_SMBALERT_EN(n) (((n)&0x01) << 25)
|
||||
|
||||
#define LL_IIC_CON0_SMBHOST_ADR_EN(n) (((n)&0x01) << 24)
|
||||
|
||||
/*! IIC received NACK signal interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON0_STRONG_DRV_EN (1UL << 23)
|
||||
/*! IIC received NACK signal interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON0_RX_NACK_IE_EN (1UL << 22)
|
||||
/*! IIC arbitration loss interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON0_AL_IE_EN (1UL << 21)
|
||||
/*! IIC received STOP signal interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON0_STOP_IE_EN (1UL << 20)
|
||||
|
||||
#define LL_IIC_CON0_ADR_MTH_IE(n) (((n)&0x01) << 19)
|
||||
|
||||
#define LL_IIC_CON0_I2C_FILTER_MAX(n) (((n)&0x1F) << 14)
|
||||
|
||||
#define LL_IIC_CON0_I2C_AL_EN(n) (((n)&0x01) << 13)
|
||||
/*! IIC slave broadcast interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON0_BROADCAST_IE_EN (1UL << 12)
|
||||
|
||||
#define LL_IIC_CON0_ISP_CMD_LEN(n) (((n)&0x0F) << 8)
|
||||
|
||||
#define LL_IIC_CON0_ISP_MODE_EN (1UL << 7)
|
||||
|
||||
#define LL_IIC_CON0_TIMEOUTB_IE(n) (((n)&0x01) << 3)
|
||||
|
||||
#define LL_IIC_CON0_TIMEOUTA_IE(n) (((n)&0x01) << 2)
|
||||
/*! The IIC responds to the NACK signal after receiving the data
|
||||
*/
|
||||
#define LL_IIC_CON0_TX_NACK (1UL << 1)
|
||||
/*! IIC slave address bit width
|
||||
*/
|
||||
#define LL_IIC_CON0_SLAVE_ADR_WIDTH(n) (((n)&0x01) << 0)
|
||||
|
||||
|
||||
/***** CON1(for IIC) Register *****/
|
||||
|
||||
#define LL_IIC_CON1_PING_PONG_EN(n) ((n&0x1) << 12)
|
||||
|
||||
#define LL_IIC_CON1_CLRBUFCNT_CLRSSP_EN(n) ((n&0x1) << 11)
|
||||
|
||||
#define LL_IIC_CON1_RX_TIMEOUT_IE(n) ((n&0x1) << 10)
|
||||
|
||||
/*! IIC DMA interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON1_DMA_IE_EN (1UL << 9)
|
||||
/*! IIC FIFO overflow interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON1_BUF_OV_IE_EN (1UL << 8)
|
||||
/*! IIC RX FIFO not empty interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON1_RX_BUF_NOT_EMPTY_IE_EN (1UL << 7)
|
||||
/*! IIC TX FIFO not full interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON1_TX_BUF_NOT_FULL_IE_EN (1UL << 6)
|
||||
/*! IIC transfers one frame interrupt enable
|
||||
*/
|
||||
#define LL_IIC_CON1_SSP_IE_EN (1UL << 5)
|
||||
/*! IIC DMA enable
|
||||
*/
|
||||
#define LL_IIC_CON1_DMA_EN (1UL << 4)
|
||||
/*! The IIC is set to the TX direction
|
||||
*/
|
||||
#define LL_IIC_CON1_TX_EN (1UL << 3)
|
||||
/*! IIC working mode
|
||||
*/
|
||||
#define LL_IIC_CON1_MODE(n) (((n)&0x01) << 2)
|
||||
/*! IIC module selet
|
||||
*/
|
||||
#define LL_IIC_CON1_IIC_SEL (1UL << 1)
|
||||
|
||||
/*! SPI/IIC module enable
|
||||
*/
|
||||
#define LL_IIC_CON1_SSP_EN (1UL << 0)
|
||||
|
||||
|
||||
/***** SSP CMD DATA(for IIC) Register *****/
|
||||
/*! IIC master transfers START signal
|
||||
*/
|
||||
#define LL_IIC_CMD_DATA_START_BIT_EN (1UL << 8)
|
||||
/*! IIC master transfers STOP signal
|
||||
*/
|
||||
#define LL_IIC_CMD_DATA_STOP_BIT_EN (1UL << 9)
|
||||
/*! Write data
|
||||
*/
|
||||
#define LL_IIC_CMD_DATA_WRITE(n) (((n)&0xFF) << 0)
|
||||
/*! Read data
|
||||
*/
|
||||
#define LL_IIC_CMD_DATA_READ(n) (((n)>>0) & 0xFF)
|
||||
|
||||
|
||||
/***** BAUD(for IIC) Register *****/
|
||||
#define LL_IIC_TIMECON_PRESC(n) (((n)&0x0F) << 28)
|
||||
|
||||
#define LL_IIC_TIMECON_SCLDEL(n) (((n)&0x0F) << 24)
|
||||
|
||||
#define LL_IIC_TIMECON_SDADEL(n) (((n)&0x0F) << 20)
|
||||
|
||||
#define LL_IIC_TIMECON_SCLH(n) (((n)&0x3FF) << 10)
|
||||
|
||||
#define LL_IIC_TIMECON_SCLL(n) (((n)&0x3FF) << 0)
|
||||
|
||||
|
||||
/***** DMA Tx LEN(for IIC) Register *****/
|
||||
/*! Set DMA Tx length(12bit)
|
||||
*/
|
||||
#define LL_IIC_DMA_TX_LEN(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx CNT(for IIC) Register *****/
|
||||
/*! The length of the byte of the received data(12bit)
|
||||
*/
|
||||
#define LL_IIC_DMA_TX_CNT(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx STADR(for IIC) Register *****/
|
||||
/*! DMA Tx start address(13bit)
|
||||
*/
|
||||
#define LL_IIC_DMA_TX_STADR(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx LEN(for IIC) Register *****/
|
||||
/*! Set DMA Rx length(12bit)
|
||||
*/
|
||||
#define LL_IIC_DMA_RX_LEN(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx CNT(for IIC) Register *****/
|
||||
/*! The length of the byte of the received data(12bit)
|
||||
*/
|
||||
#define LL_IIC_DMA_RX_CNT(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx STADR(for IIC) Register *****/
|
||||
/*! DMA Rx start address(13bit)
|
||||
*/
|
||||
#define LL_IIC_DMA_RX_STADR(n) (n)
|
||||
|
||||
|
||||
/***** STA1(for IIC) Register *****/
|
||||
#define LL_IIC_STA1_HSYNC_PEND_CLR_BUF_CNT (1UL << 31)
|
||||
|
||||
#define LL_IIC_STA1_HSYNC_PEND (1UL << 21)
|
||||
|
||||
#define LL_IIC_STA1_VSYNC_PEND (1UL << 20)
|
||||
|
||||
#define LL_IIC_STA1_DMA_PPBUF_SEL (1UL << 19)
|
||||
|
||||
#define LL_IIC_STA1_RX_TIMEOUT_PEND (1UL << 18)
|
||||
|
||||
#define LL_IIC_STA1_MODF (1UL << 17)
|
||||
|
||||
#define LL_IIC_STA1_SLAVE_WRONG_CMD_PENDING (1UL << 16)
|
||||
|
||||
#define LL_IIC_STA1_SLAVE_WIREMODE_CFG_PENDING (1UL << 15)
|
||||
|
||||
#define LL_IIC_STA1_SLAVE_RDSTATUS_PENDING (1UL << 14)
|
||||
|
||||
#define LL_IIC_STA1_SLAVE_RDDATA_PENDING (1UL << 13)
|
||||
|
||||
#define LL_IIC_STA1_SLAVE_WRDATA_PENDING (1UL << 12)
|
||||
|
||||
#define LL_IIC_STA1_CLEAR_BUF_CNT (1UL << 9)
|
||||
/*! Get how many bytes of valid data in the FIFO
|
||||
*/
|
||||
#define LL_IIC_STA1_BUF_CNT(n) (((n)& 0x07) )
|
||||
|
||||
#define LL_IIC_STA1_MASTER_RX_BUSY_PENDING (1UL << 8)
|
||||
|
||||
#define LL_IIC_STA1_SLAVE_CS_STATE (1UL << 7)
|
||||
|
||||
#define LL_IIC_STA1_SSP_BUSY_PENDING (1UL << 6)
|
||||
|
||||
#define LL_IIC_STA1_NSS_POS_PENDING (1UL << 5)
|
||||
|
||||
#define LL_IIC_STA1_DMA_PENDING (1UL << 4)
|
||||
|
||||
#define LL_IIC_STA1_BUF_OV_PENDING (1UL << 3)
|
||||
|
||||
#define LL_IIC_STA1_BUF_EMPTY_PENDING (1UL << 2)
|
||||
|
||||
#define LL_IIC_STA1_BUF_FULL_PENDING (1UL << 1)
|
||||
|
||||
#define LL_IIC_STA1_DONE_PENDING (1UL << 0)
|
||||
|
||||
|
||||
/***** STA2(for IIC) Register *****/
|
||||
#define LL_IIC_STA2_STATE(n) ((n&0x07)<<16)
|
||||
#define LL_IIC_STA2_TIMEOUTB_PEND(n) ((n&0x01)<<13)
|
||||
#define LL_IIC_STA2_TIMEOUTA_PEND(n) ((n&0x01)<<12)
|
||||
#define LL_IIC_STA2_SBC_PEND(n) ((n&0x01)<<11)
|
||||
#define LL_IIC_STA2_ALERT_PEND(n) ((n&0x01)<<10)
|
||||
#define LL_IIC_STA2_I2C_AL(n) ((n&0x01)<<9)
|
||||
#define LL_IIC_STA2_RX_NACK(n) ((n&0x01)<<8)
|
||||
#define LL_IIC_STA2_STOP_PEND(n) ((n&0x01)<<7)
|
||||
#define LL_IIC_STA2_I2C_BUS_BUSY(n) ((n&0x01)<<6)
|
||||
#define LL_IIC_STA2_SLV_RW(n) ((n&0x01)<<5)
|
||||
#define LL_IIC_STA2_ADRMTHCODE(n) ((n&0x07)<<2)
|
||||
#define LL_IIC_STA2_SLV_ADDRED(n) ((n&0x01)<<1)
|
||||
#define LL_IIC_STA2_ADR_MTH_PEND(n) ((n&0x01)<<0)
|
||||
|
||||
|
||||
/***** OWNADRCON(for IIC) Register *****/
|
||||
#define LL_IIC_OWNADRCON_OWN_ADR2_MASK(n) ((n&0x07)<<24)
|
||||
#define LL_IIC_OWNADRCON_OWN_ADR2(n) ((n&0x7F)<<17)
|
||||
#define LL_IIC_OWNADRCON_OWN_ADR2_EN(n) ((n&0x01)<<16)
|
||||
#define LL_IIC_OWNADRCON_OWN_ADR1_S(n) ((n&0x01)<<11)
|
||||
#define LL_IIC_OWNADRCON_OWN_ADR1_EN(n) ((n&0x01)<<10)
|
||||
#define LL_IIC_OWNADRCON_OWN_ADR1(n) ((n&0x3FF)<<0)
|
||||
|
||||
|
||||
/***** RBUF(for IIC) Register *****/
|
||||
#define LL_IIC_RBUF(n) ((n))
|
||||
|
||||
/***** TIMEOUTCON(for IIC) Register *****/
|
||||
#define LL_IIC_TIMEOUTCON_TIMEOUTB_EN(n) ((n&01)<<31)
|
||||
#define LL_IIC_TIMEOUTCON_TIMEOUTB(n) ((n&0xFFF)<<16)
|
||||
#define LL_IIC_TIMEOUTCON_TIMEOUTA_EN(n) ((n&01)<<15)
|
||||
#define LL_IIC_TIMEOUTCON_TIMEOUTA_S(n) ((n&01)<<12)
|
||||
#define LL_IIC_TIMEOUTCON_TIMEOUTA(n) ((n&0xFFF)<<0)
|
||||
|
||||
/***** RX TIMEOUTCON(for IIC) Register *****/
|
||||
#define LL_IIC_RXTIMEOUTCON_RX_TIMEOUT(n) ((n&0x1ffffff7)<<1)
|
||||
#define LL_IIC_RXTIMEOUTCON_RX_TIMEOUT_EN(n) ((n&0x1)<<0)
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
/*! IIC does not transmit signals other than ACK.
|
||||
*/
|
||||
LL_IIC_NONE_FLAG = 0,
|
||||
/*! IIC sends START signal
|
||||
*/
|
||||
LL_IIC_START_FLAG = 1,
|
||||
/*! IIC sends STOP signal
|
||||
*/
|
||||
LL_IIC_STOP_FLAG = 2,
|
||||
/*! IIC sends NACK signal
|
||||
*/
|
||||
LL_IIC_NACK_FLAG = 4,
|
||||
} TYPE_ENUM_LL_IIC_FLAG;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief IIC
|
||||
*/
|
||||
struct hgi2c_v1_hw {
|
||||
__IO uint32_t CON0;
|
||||
__IO uint32_t CON1;
|
||||
__IO uint32_t CMD_DATA;
|
||||
__IO uint32_t TIMECON;
|
||||
__IO uint32_t TDMALEN;
|
||||
__IO uint32_t RDMALEN;
|
||||
__IO uint32_t TDMACNT;
|
||||
__IO uint32_t RDMACNT;
|
||||
__IO uint32_t TSTADR;
|
||||
__IO uint32_t RSTADR;
|
||||
__IO uint32_t STA1;
|
||||
__IO uint32_t STA2;
|
||||
__IO uint32_t SLAVESTA;
|
||||
__IO uint32_t OWNADRCON;
|
||||
__IO uint32_t RBUF;
|
||||
__IO uint32_t TIMEOUTCON;
|
||||
__IO uint32_t RXTIMEOUTCON;
|
||||
__IO uint32_t RSTADR1;
|
||||
__IO uint32_t VSYNC_TCON;
|
||||
__IO uint32_t HSYNC_TCON;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _HGI2C_V1_HW_H */
|
||||
908
sdk/driver/i2s/hgi2s_v0.c
Normal file
908
sdk/driver/i2s/hgi2s_v0.c
Normal file
@@ -0,0 +1,908 @@
|
||||
/**
|
||||
* @file hgi2s_v0.c
|
||||
* @author bxd
|
||||
* @brief iis
|
||||
* @version
|
||||
* TXW80X; TXW81X
|
||||
* @date 2023-08-02
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "errno.h"
|
||||
#include "dev.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "hal/i2s.h"
|
||||
#include "dev/i2s/hgi2s_v0.h"
|
||||
#include "hgi2s_v0_hw.h"
|
||||
|
||||
|
||||
#define __OVER_SAMPPLE_RATE (512)
|
||||
|
||||
struct __iis_cfg {
|
||||
uint32 mclk_div;
|
||||
uint32 baud_div;
|
||||
uint32 wscon_div;
|
||||
};
|
||||
|
||||
const struct __iis_cfg iis_cfg_8k[] = {
|
||||
|
||||
/*!
|
||||
* over_sample: 512.000
|
||||
* sample_rate: 8000.000
|
||||
* 8 bit
|
||||
*/
|
||||
//mclk_rate:4.103MHz, bclk_rate:128.205KHz, sample_rate:8012.821Hz, error_rate:1602.56ppm,mclk = 116, baud = 15, wscon = 7
|
||||
{
|
||||
.mclk_div = 116,
|
||||
.baud_div = 15,
|
||||
.wscon_div = 7,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 512.000
|
||||
* sample_rate: 8000.000
|
||||
* 16 bit
|
||||
*/
|
||||
//mclk_rate:4.103MHz, bclk_rate:256.410KHz, sample_rate:8012.821Hz, error_rate:1602.56ppm,mclk = 116, baud = 7, wscon = 15
|
||||
{
|
||||
.mclk_div = 116,
|
||||
.baud_div = 7,
|
||||
.wscon_div = 15,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 768.000
|
||||
* sample_rate: 8000.000
|
||||
* 24 bit
|
||||
*/
|
||||
//mclk_rate:6.154MHz, bclk_rate:384.615KHz, sample_rate:8012.821Hz, error_rate:1602.56ppm,mclk = 77, baud = 7, wscon = 23
|
||||
{
|
||||
.mclk_div = 77,
|
||||
.baud_div = 7,
|
||||
.wscon_div = 23,
|
||||
}
|
||||
};
|
||||
|
||||
const struct __iis_cfg iis_cfg_16k[] = {
|
||||
|
||||
/*!
|
||||
* over_sample: 256.000
|
||||
* sample_rate: 16000.000
|
||||
* 8 bit
|
||||
*/
|
||||
//mclk_rate:4.103MHz, bclk_rate:256.410KHz, sample_rate:16025.641Hz, error_rate:1602.56ppm,mclk = 116, baud = 7, wscon = 7
|
||||
{
|
||||
.mclk_div = 116,
|
||||
.baud_div = 7,
|
||||
.wscon_div = 7,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 256.000
|
||||
* sample_rate: 16000.000
|
||||
* 16 bit
|
||||
*/
|
||||
//mclk_rate:4.103MHz, bclk_rate:512.821KHz, sample_rate:16025.641Hz, error_rate:1602.56ppm,mclk = 116, baud = 3, wscon = 15
|
||||
{
|
||||
.mclk_div = 116,
|
||||
.baud_div = 3,
|
||||
.wscon_div = 15,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 384.000
|
||||
* sample_rate: 16000.000
|
||||
* 24 bit
|
||||
*/
|
||||
//mclk_rate:6.154MHz, bclk_rate:769.231KHz, sample_rate:16025.641Hz, error_rate:1602.56ppm,mclk = 77, baud = 3, wscon = 23
|
||||
{
|
||||
.mclk_div = 77,
|
||||
.baud_div = 3,
|
||||
.wscon_div = 23,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const struct __iis_cfg iis_cfg_44_1k[] = {
|
||||
|
||||
/*!
|
||||
* over_sample: 128.000
|
||||
* sample_rate: 44100.000
|
||||
* 16 bit
|
||||
*/
|
||||
//mclk_rate:5.647MHz, bclk_rate:705.882KHz, sample_rate:44117.647Hz, error_rate:400.16ppm,mclk = 84, baud = 3, wscon = 7
|
||||
{
|
||||
.mclk_div = 84,
|
||||
.baud_div = 3,
|
||||
.wscon_div = 7,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 128.000
|
||||
* sample_rate: 44100.000
|
||||
* 16 bit
|
||||
*/
|
||||
//mclk_rate:5.647MHz, bclk_rate:1411.765KHz, sample_rate:44117.647Hz, error_rate:400.16ppm,mclk = 84, baud = 1, wscon = 15
|
||||
{
|
||||
.mclk_div = 84,
|
||||
.baud_div = 1,
|
||||
.wscon_div = 15,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 128.000
|
||||
* sample_rate: 44100.000
|
||||
* 24 bit
|
||||
*/
|
||||
//no support
|
||||
|
||||
};
|
||||
|
||||
const struct __iis_cfg iis_cfg_48k[] = {
|
||||
|
||||
/*!
|
||||
* over_sample: 256.000
|
||||
* sample_rate: 48000.000
|
||||
* 8 bit
|
||||
*/
|
||||
//mclk_rate:12.308MHz, bclk_rate:769.231KHz, sample_rate:48076.923Hz, error_rate:1602.56ppm,mclk = 38, baud = 7, wscon = 7
|
||||
{
|
||||
.mclk_div = 38,
|
||||
.baud_div = 7,
|
||||
.wscon_div = 7,
|
||||
},
|
||||
|
||||
|
||||
/*!
|
||||
* over_sample: 768.000
|
||||
* sample_rate: 48000.000
|
||||
* 16 bit
|
||||
*/
|
||||
//mclk_rate:36.923MHz, bclk_rate:1538.462KHz, sample_rate:48076.923Hz, error_rate:1602.56ppm,mclk = 12, baud = 11, wscon = 15
|
||||
{
|
||||
.mclk_div = 12,
|
||||
.baud_div = 11,
|
||||
.wscon_div = 15,
|
||||
},
|
||||
|
||||
/*!
|
||||
* over_sample: 768.000
|
||||
* sample_rate: 48000.000
|
||||
* 16 bit
|
||||
*/
|
||||
//mclk_rate:36.923MHz, bclk_rate:2307.692KHz, sample_rate:48076.923Hz, error_rate:1602.56ppm,mclk = 12, baud = 7, wscon = 23
|
||||
{
|
||||
.mclk_div = 12,
|
||||
.baud_div = 7,
|
||||
.wscon_div = 23,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
/* I2S LOW LAYER FUNCTION */
|
||||
/**********************************************************************************/
|
||||
static int32 hgi2s_v0_switch_hal_i2s_mode(enum i2s_mode mode) {
|
||||
|
||||
switch (mode) {
|
||||
case (I2S_MODE_MASTER ):
|
||||
return 0;
|
||||
break;
|
||||
case (I2S_MODE_SLAVE ):
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_switch_hal_i2s_channel(enum i2s_channel channel) {
|
||||
|
||||
switch (channel) {
|
||||
case (I2S_CHANNEL_MONO ):
|
||||
return 1;
|
||||
break;
|
||||
case (I2S_CHANNEL_STEREO):
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_switch_hal_i2s_sample_bits(enum i2s_sample_bits bits) {
|
||||
|
||||
switch (bits) {
|
||||
case (I2S_SAMPLE_BITS_8BITS ):
|
||||
return 8;
|
||||
break;
|
||||
case (I2S_SAMPLE_BITS_16BITS):
|
||||
return 16;
|
||||
break;
|
||||
case (I2S_SAMPLE_BITS_24BITS):
|
||||
return 24;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_switch_hal_i2s_data_fmt(enum i2s_data_fmt data_fmt) {
|
||||
|
||||
switch (data_fmt) {
|
||||
case (I2S_DATA_FMT_I2S):
|
||||
return 0;
|
||||
break;
|
||||
case (I2S_DATA_FMT_LSB):
|
||||
return 1;
|
||||
break;
|
||||
case (I2S_DATA_FMT_MSB):
|
||||
return 2;
|
||||
break;
|
||||
case (I2S_DATA_FMT_PCM):
|
||||
return 3;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct __iis_cfg* hgi2s_v0_switch_hal_i2s_sample_freq(enum i2s_sample_freq frequency, enum i2s_sample_bits bits)
|
||||
{
|
||||
const struct __iis_cfg *p_iis_cfg = NULL;
|
||||
int8 index = -1;
|
||||
|
||||
if (I2S_SAMPLE_BITS_8BITS ==bits) {index=0;}
|
||||
if (I2S_SAMPLE_BITS_16BITS==bits) {index=1;}
|
||||
if (I2S_SAMPLE_BITS_24BITS==bits) {index=2;}
|
||||
|
||||
switch (frequency) {
|
||||
case (I2S_SAMPLE_FREQ_8K):
|
||||
p_iis_cfg = iis_cfg_8k;
|
||||
break;
|
||||
case (I2S_SAMPLE_FREQ_16K):
|
||||
p_iis_cfg = iis_cfg_16k;
|
||||
break;
|
||||
case (I2S_SAMPLE_FREQ_44_1K):
|
||||
p_iis_cfg = iis_cfg_44_1k;
|
||||
if (I2S_SAMPLE_BITS_24BITS==bits) {
|
||||
index=-1; p_iis_cfg=NULL;
|
||||
os_printf("iis info: no support 44.1k, 24bit\r\n");
|
||||
}
|
||||
break;
|
||||
case (I2S_SAMPLE_FREQ_48K ):
|
||||
p_iis_cfg = iis_cfg_48k;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((index==-1) || (p_iis_cfg==NULL)) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &p_iis_cfg[index];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline void hgi2s_v0_set_mclk(struct hgi2s_v0_hw *p_i2s, uint32 mclk_div) {
|
||||
//uint32 mclk_div = 0;
|
||||
|
||||
//IIS0
|
||||
if (IIS0_BASE == (uint32)p_i2s) {
|
||||
SYSCTRL_REG_OPT(
|
||||
SYSCTRL->SYS_CON3 = (SYSCTRL->SYS_CON3 & ~(0x01 << 28)) | (0 << 28);
|
||||
);
|
||||
|
||||
#if 0
|
||||
/* i2s module clk use pll0 & pll1 */
|
||||
os_printf("iis0 pll clk:%d\r\n", peripheral_clock_get(HG_APB0_PT_IIS0));
|
||||
os_printf("iis1 pll clk:%d\r\n", peripheral_clock_get(HG_APB0_PT_IIS0));
|
||||
mclk_div = ((peripheral_clock_get(HG_APB0_PT_IIS0)+((freq*__OVER_SAMPPLE_RATE)/2)) / (freq*__OVER_SAMPPLE_RATE));
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* FPGA: 96MHz */
|
||||
mclk_div = (96000000 / (freq*256));
|
||||
#endif
|
||||
|
||||
SYSCTRL_REG_OPT(
|
||||
SYSCTRL->CLK_CON0 = (SYSCTRL->CLK_CON0 & ~(0x7f << 16)) | ((mclk_div) << 16);
|
||||
);
|
||||
}
|
||||
//IIS1
|
||||
else if(IIS1_BASE == (uint32)p_i2s){
|
||||
SYSCTRL_REG_OPT(
|
||||
SYSCTRL->SYS_CON3 = (SYSCTRL->SYS_CON3 & ~(0x01 << 29)) | (0 << 29);
|
||||
);
|
||||
|
||||
#if 0
|
||||
/* i2s module clk use pll0 & pll1 */
|
||||
mclk_div = (peripheral_clock_get(HG_APB0_PT_IIS1) / (freq*256));
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* FPGA: 96MHz */
|
||||
mclk_div = (96000000 / (freq*256));
|
||||
#endif
|
||||
|
||||
SYSCTRL_REG_OPT(
|
||||
SYSCTRL->CLK_CON0 = (SYSCTRL->CLK_CON0 & ~(0x7f << 23)) | ((mclk_div) << 23);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hgi2s_v0_enable(struct hgi2s_v0_hw *p_i2s) {
|
||||
p_i2s->CON |= LL_I2S_CON_ENABLE(1);
|
||||
}
|
||||
|
||||
static inline void hgi2s_v0_disable(struct hgi2s_v0_hw *p_i2s) {
|
||||
p_i2s->CON &= ~ LL_I2S_CON_ENABLE(1);
|
||||
}
|
||||
|
||||
static inline void hgi2s_v0_set_tx(struct hgi2s_v0_hw *p_i2s) {
|
||||
p_i2s->CON |= LL_I2S_CON_WORKMODE(1);
|
||||
}
|
||||
|
||||
static inline void hgi2s_v0_set_rx(struct hgi2s_v0_hw *p_i2s) {
|
||||
p_i2s->CON &= ~ LL_I2S_CON_WORKMODE(1);
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_set_wsclk_pol(struct hgi2s_v0_hw *p_i2s, uint32 value) {
|
||||
|
||||
hgi2s_v0_disable(p_i2s);
|
||||
|
||||
if (value) {
|
||||
p_i2s->CON |= LL_I2S_CON_WSPOL(1);
|
||||
} else {
|
||||
p_i2s->CON &= ~ LL_I2S_CON_WSPOL(1);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_set_sample_bits(struct hgi2s_v0_hw *p_i2s, enum i2s_sample_bits bits) {
|
||||
|
||||
int32 i2s_sample_bits_to_reg = 0;
|
||||
|
||||
i2s_sample_bits_to_reg = hgi2s_v0_switch_hal_i2s_sample_bits(bits);
|
||||
|
||||
if ((-1) == i2s_sample_bits_to_reg) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
hgi2s_v0_disable(p_i2s);
|
||||
|
||||
p_i2s->BIT_SET = i2s_sample_bits_to_reg;
|
||||
p_i2s->WS_CON = i2s_sample_bits_to_reg;
|
||||
p_i2s->BAUD = (64 / i2s_sample_bits_to_reg) - 1;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_set_channel(struct hgi2s_v0_hw *p_i2s, enum i2s_channel channel) {
|
||||
|
||||
int32 i2s_channel_to_reg = 0;
|
||||
|
||||
i2s_channel_to_reg = hgi2s_v0_switch_hal_i2s_channel(channel);
|
||||
|
||||
if ((-1) == i2s_channel_to_reg) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
hgi2s_v0_disable(p_i2s);
|
||||
|
||||
p_i2s->CON = (p_i2s->CON &~ LL_I2S_CON_MONO(0x3)) | LL_I2S_CON_MONO(i2s_channel_to_reg);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_set_data_fmt(struct hgi2s_v0_hw *p_i2s, enum i2s_data_fmt data_fmt) {
|
||||
|
||||
int32 i2s_data_fmt_to_reg = 0;
|
||||
|
||||
i2s_data_fmt_to_reg = hgi2s_v0_switch_hal_i2s_data_fmt(data_fmt);
|
||||
|
||||
if ((-1) == i2s_data_fmt_to_reg) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
hgi2s_v0_disable(p_i2s);
|
||||
|
||||
p_i2s->CON = (p_i2s->CON &~ LL_I2S_CON_FRMT(0x3)) | LL_I2S_CON_FRMT(i2s_data_fmt_to_reg);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_set_debounce(struct hgi2s_v0_hw *p_i2s, uint32 enable) {
|
||||
|
||||
hgi2s_v0_disable(p_i2s);
|
||||
|
||||
if (!enable) {
|
||||
p_i2s->CON |= LL_I2S_CON_BCLKDBSBPS(1) | LL_I2S_CON_RXDBSBPS(1) | LL_I2S_CON_WSCLKDBSBPS(1);
|
||||
} else {
|
||||
p_i2s->CON &= ~(LL_I2S_CON_BCLKDBSBPS(1) | LL_I2S_CON_RXDBSBPS(1) | LL_I2S_CON_WSCLKDBSBPS(1));
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_set_duplex(struct hgi2s_v0 *dev, uint32 enable) {
|
||||
|
||||
if (enable) {
|
||||
dev->duplex_en = 1;
|
||||
} else {
|
||||
dev->duplex_en = 0;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
/* I2S ATTCH FUNCTION */
|
||||
/**********************************************************************************/
|
||||
int32 hgi2s_v0_open(struct i2s_device *i2s, enum i2s_mode mode, enum i2s_sample_freq frequency, enum i2s_sample_bits bits)
|
||||
{
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
const struct __iis_cfg *p_iis_cfg = NULL;
|
||||
uint32 i2s_reg_con = 0;
|
||||
int32 i2s_mode_to_reg = 0;
|
||||
int32 i2s_channel_to_reg = 0;
|
||||
int32 i2s_sample_bits_to_reg = 0;
|
||||
int32 i2s_data_fmt_to_reg = 0;
|
||||
//int32 i2s_sample_freq_to_reg = 0;
|
||||
|
||||
if (dev->opened) {
|
||||
if (!dev->dsleep) {
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/* hal enum */
|
||||
i2s_mode_to_reg = hgi2s_v0_switch_hal_i2s_mode(mode );
|
||||
i2s_channel_to_reg = hgi2s_v0_switch_hal_i2s_channel(I2S_CHANNEL_STEREO);
|
||||
i2s_data_fmt_to_reg = hgi2s_v0_switch_hal_i2s_data_fmt(I2S_DATA_FMT_I2S );
|
||||
i2s_sample_bits_to_reg = hgi2s_v0_switch_hal_i2s_sample_bits(bits );
|
||||
p_iis_cfg = hgi2s_v0_switch_hal_i2s_sample_freq(frequency,bits);
|
||||
|
||||
if (((-1) == i2s_mode_to_reg ) || \
|
||||
((-1) == i2s_channel_to_reg ) || \
|
||||
((-1) == i2s_data_fmt_to_reg ) || \
|
||||
((-1) == i2s_sample_bits_to_reg) || \
|
||||
((NULL) == p_iis_cfg)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* make sure the sys_clk */
|
||||
if (0 != ((peripheral_clock_get(HG_APB0_PT_IIS0)*2) % (i2s_sample_freq_to_reg * 256))) {
|
||||
return RET_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* pin config */
|
||||
if (pin_func(dev->dev.dev.dev_id , 1) != RET_OK) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* open I2S clk
|
||||
*/
|
||||
if (IIS0_BASE == (uint32)hw) {
|
||||
sysctrl_iis0_clk_open();
|
||||
} else if (IIS1_BASE == (uint32)hw) {
|
||||
sysctrl_iis1_clk_open();
|
||||
}
|
||||
|
||||
/*
|
||||
* clear the regs
|
||||
*/
|
||||
hw->BAUD = 0;
|
||||
hw->BIT_SET = 0;
|
||||
hw->CON = 0;
|
||||
hw->DMA_LEN = 0;
|
||||
hw->DMA_STADR = 0;
|
||||
hw->WS_CON = 0;
|
||||
hw->STA = 0xFFFF;
|
||||
|
||||
/* reg config */
|
||||
i2s_reg_con = hw->CON;
|
||||
|
||||
i2s_reg_con = LL_I2S_CON_MODE(i2s_mode_to_reg ) |
|
||||
LL_I2S_CON_MONO(i2s_channel_to_reg ) |
|
||||
LL_I2S_CON_MCLK_OE(1 ) | /* open mclk to io */
|
||||
LL_I2S_CON_WSPOL(0 ) |
|
||||
LL_I2S_CON_BCKPOL(0 ) |
|
||||
LL_I2S_CON_FRMT(i2s_data_fmt_to_reg) ;
|
||||
|
||||
if (mode == I2S_MODE_SLAVE) {
|
||||
i2s_reg_con |= (LL_I2S_CON_BCLKDBSBPS(0) | LL_I2S_CON_RXDBSBPS(0) | LL_I2S_CON_WSCLKDBSBPS(0));
|
||||
} else {
|
||||
//close debounce
|
||||
i2s_reg_con |= (LL_I2S_CON_BCLKDBSBPS(1) | LL_I2S_CON_RXDBSBPS(1) | LL_I2S_CON_WSCLKDBSBPS(1));
|
||||
}
|
||||
|
||||
hw->CON = i2s_reg_con;
|
||||
hw->WS_CON = p_iis_cfg->wscon_div;
|
||||
hw->BAUD = p_iis_cfg->baud_div;
|
||||
hw->BIT_SET = i2s_sample_bits_to_reg - 1;
|
||||
|
||||
if (mode == I2S_MODE_SLAVE) {
|
||||
hgi2s_v0_set_mclk(hw, 5);
|
||||
} else {
|
||||
hgi2s_v0_set_mclk(hw, p_iis_cfg->mclk_div);
|
||||
}
|
||||
|
||||
|
||||
dev->opened = 1;
|
||||
dev->duplex_en = 0;
|
||||
dev->dsleep = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hgi2s_v0_close(struct i2s_device *i2s) {
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if (!dev->opened) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* close IIS clk
|
||||
*/
|
||||
if (IIS0_BASE == (uint32)hw) {
|
||||
sysctrl_iis0_clk_close();
|
||||
} else if (IIS1_BASE == (uint32)hw) {
|
||||
sysctrl_iis1_clk_close();
|
||||
}
|
||||
|
||||
|
||||
irq_disable(dev->irq_num );
|
||||
pin_func(dev->dev.dev.dev_id, 0);
|
||||
hgi2s_v0_disable(hw );
|
||||
|
||||
dev->opened = 0;
|
||||
dev->duplex_en = 0;
|
||||
dev->dsleep = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hgi2s_v0_write(struct i2s_device *i2s, const void* buf, uint32 len) {
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
uint32 len_to_reg = 0;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
len_to_reg = len;
|
||||
|
||||
hw->DMA_STADR = (uint32)buf;
|
||||
hw->DMA_LEN = len_to_reg;
|
||||
|
||||
hgi2s_v0_set_tx(hw);
|
||||
|
||||
if (!dev->duplex_en) {
|
||||
hgi2s_v0_enable(hw);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hgi2s_v0_read(struct i2s_device *i2s, void* buf, uint32 len) {
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
uint32 len_to_reg = 0;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
len_to_reg = len;
|
||||
|
||||
hw->DMA_STADR = (uint32)buf;
|
||||
hw->DMA_LEN = len_to_reg;
|
||||
|
||||
hgi2s_v0_set_rx(hw);
|
||||
|
||||
if (!dev->duplex_en) {
|
||||
hgi2s_v0_enable(hw);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hgi2s_v0_ioctl(struct i2s_device *i2s, uint32 cmd, uint32 param) {
|
||||
|
||||
int32 ret_val = RET_OK;
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
case (I2S_IOCTL_CMD_SET_WSCLK_POL):
|
||||
ret_val = hgi2s_v0_set_wsclk_pol(hw , param);
|
||||
break;
|
||||
case (I2S_IOCTL_CMD_SET_SAMPLE_BITS):
|
||||
ret_val = hgi2s_v0_set_sample_bits(hw, param);
|
||||
break;
|
||||
case (I2S_IOCTL_CMD_SET_CHANNEL):
|
||||
ret_val = hgi2s_v0_set_channel(hw , param);
|
||||
break;
|
||||
case (I2S_IOCTL_CMD_SET_DATA_FMT):
|
||||
ret_val = hgi2s_v0_set_data_fmt(hw , param);
|
||||
break;
|
||||
case (I2S_IOCTL_CMD_SET_DEBOUNCE):
|
||||
ret_val = hgi2s_v0_set_debounce(hw , param);
|
||||
break;
|
||||
case (I2S_IOCTL_CMD_SET_DUPLEX):
|
||||
ret_val = hgi2s_v0_set_duplex(dev , param);
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SLEEP
|
||||
static int32 hgi2s_v0_suspend(struct dev_obj *obj)
|
||||
{
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)obj;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if (0 > os_mutex_lock(&dev->bp_suspend_lock, 10000)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Close the IIS
|
||||
*/
|
||||
hw->CON &= ~ BIT(0);
|
||||
|
||||
|
||||
pin_func(dev->dev.dev.dev_id , 0);
|
||||
|
||||
|
||||
/*
|
||||
* close irq
|
||||
*/
|
||||
irq_disable(dev->irq_num);
|
||||
|
||||
/*
|
||||
* clear pending
|
||||
*/
|
||||
hw->STA = 0xFFFFFFFF;
|
||||
|
||||
os_memset((void *)&dev->bp_regs, 0, sizeof(dev->bp_regs));
|
||||
|
||||
/*
|
||||
* save the reglist
|
||||
*/
|
||||
dev->bp_regs.con = hw->CON;
|
||||
dev->bp_regs.bit_set = hw->BIT_SET;
|
||||
dev->bp_regs.baud = hw->BAUD;
|
||||
dev->bp_regs.ws_con = hw->WS_CON;
|
||||
dev->bp_regs.dma_stadr = hw->DMA_STADR;
|
||||
dev->bp_regs.dma_len = hw->DMA_LEN;
|
||||
|
||||
/*
|
||||
* save the irq_hdl created by user
|
||||
*/
|
||||
dev->bp_irq_hdl = dev->irq_hdl;
|
||||
dev->bp_irq_data = dev->irq_data;
|
||||
|
||||
/*
|
||||
* close IIS clk
|
||||
*/
|
||||
if (IIS0_BASE == (uint32)hw) {
|
||||
sysctrl_iis0_clk_close();
|
||||
} else if (IIS1_BASE == (uint32)hw) {
|
||||
sysctrl_iis1_clk_close();
|
||||
}
|
||||
|
||||
dev->dsleep = 1;
|
||||
|
||||
os_mutex_unlock(&dev->bp_suspend_lock);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgi2s_v0_resume(struct dev_obj *obj)
|
||||
{
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0*)obj;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (!dev->dsleep)) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if (0 > os_mutex_lock(&dev->bp_resume_lock, 10000)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
/* pin config */
|
||||
if (pin_func(dev->dev.dev.dev_id , 1) != RET_OK) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* open I2S clk
|
||||
*/
|
||||
if (IIS0_BASE == (uint32)hw) {
|
||||
sysctrl_iis0_clk_open();
|
||||
} else if (IIS1_BASE == (uint32)hw) {
|
||||
sysctrl_iis1_clk_open();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* recovery the reglist from sram
|
||||
*/
|
||||
hw->BIT_SET = dev->bp_regs.bit_set;
|
||||
hw->BAUD = dev->bp_regs.baud;
|
||||
hw->WS_CON = dev->bp_regs.ws_con;
|
||||
hw->DMA_STADR = dev->bp_regs.dma_stadr;
|
||||
hw->DMA_LEN = dev->bp_regs.dma_len;
|
||||
hw->CON = dev->bp_regs.con;
|
||||
|
||||
/*
|
||||
* recovery the irq handle and data
|
||||
*/
|
||||
dev->irq_hdl = dev->bp_irq_hdl;
|
||||
dev->irq_data = dev->bp_irq_data;
|
||||
|
||||
os_memset((void *)&dev->bp_regs, 0, sizeof(dev->bp_regs));
|
||||
|
||||
|
||||
/*!
|
||||
* Open the IIS
|
||||
*/
|
||||
hw->CON |= BIT(0);
|
||||
|
||||
|
||||
/*
|
||||
* open irq
|
||||
*/
|
||||
irq_enable(dev->irq_num);
|
||||
|
||||
dev->dsleep = 0;
|
||||
|
||||
os_mutex_unlock(&dev->bp_resume_lock);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* interrupt handler */
|
||||
static void hgi2s_v0_irq_handler(void *data) {
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0 *)data;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if ((hw->CON & LL_I2S_CON_HF_PEND_IE(1)) && (hw->STA & LL_I2S_STA_DMA_HF_PENGING(1))) {
|
||||
hw->STA = LL_I2S_STA_DMA_HF_PENGING(1);
|
||||
if (dev->irq_hdl) {
|
||||
dev->irq_hdl(I2S_IRQ_FLAG_HALF, dev->irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
if ((hw->CON & LL_I2S_CON_OV_PEND_IE(1)) && (hw->STA & LL_I2S_STA_DMA_OV_PENGING(1))) {
|
||||
hw->STA = LL_I2S_STA_DMA_OV_PENGING(1);
|
||||
if (dev->irq_hdl) {
|
||||
dev->irq_hdl(I2S_IRQ_FLAG_FULL, dev->irq_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* request interrupt */
|
||||
int32 hgi2s_v0_request_irq(struct i2s_device *i2s, uint32 irq_flag, i2s_irq_hdl irqhdl, uint32 irq_data) {
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0 *)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
dev->irq_hdl = irqhdl;
|
||||
dev->irq_data = irq_data;
|
||||
request_irq(dev->irq_num, hgi2s_v0_irq_handler, dev);
|
||||
|
||||
|
||||
if (irq_flag & I2S_IRQ_FLAG_HALF) {
|
||||
hw->CON |= LL_I2S_CON_HF_PEND_IE(1);
|
||||
}
|
||||
|
||||
if (irq_flag & I2S_IRQ_FLAG_FULL) {
|
||||
hw->CON |= LL_I2S_CON_OV_PEND_IE(1);
|
||||
}
|
||||
|
||||
irq_enable(dev->irq_num);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hgi2s_v0_release_irq(struct i2s_device *i2s, uint32 irq_flag) {
|
||||
|
||||
struct hgi2s_v0 *dev = (struct hgi2s_v0 *)i2s;
|
||||
struct hgi2s_v0_hw *hw = (struct hgi2s_v0_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
if (irq_flag & I2S_IRQ_FLAG_HALF) {
|
||||
hw->CON &= ~ LL_I2S_CON_HF_PEND_IE(1);
|
||||
}
|
||||
|
||||
if (irq_flag & I2S_IRQ_FLAG_FULL) {
|
||||
hw->CON &= ~ LL_I2S_CON_OV_PEND_IE(1);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const struct i2s_hal_ops i2s_v0_ops = {
|
||||
.open = hgi2s_v0_open,
|
||||
.close = hgi2s_v0_close,
|
||||
.write = hgi2s_v0_write,
|
||||
.read = hgi2s_v0_read,
|
||||
.request_irq = hgi2s_v0_request_irq,
|
||||
.release_irq = hgi2s_v0_release_irq,
|
||||
.ioctl = hgi2s_v0_ioctl,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hgi2s_v0_suspend,
|
||||
.ops.resume = hgi2s_v0_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
int32 hgi2s_v0_attach(uint32 dev_id, struct hgi2s_v0 *i2s) {
|
||||
i2s->opened = 0;
|
||||
i2s->dsleep = 0;
|
||||
i2s->irq_hdl = NULL;
|
||||
i2s->irq_data = 0;
|
||||
i2s->duplex_en = 0;
|
||||
i2s->dev.dev.ops = (const struct devobj_ops *)&i2s_v0_ops;
|
||||
#ifdef CONFIG_SLEEP
|
||||
os_mutex_init(&i2s->bp_suspend_lock);
|
||||
os_mutex_init(&i2s->bp_resume_lock);
|
||||
#endif
|
||||
irq_disable(i2s->irq_num);
|
||||
dev_register(dev_id, (struct dev_obj *)i2s);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
124
sdk/driver/i2s/hgi2s_v0_hw.h
Normal file
124
sdk/driver/i2s/hgi2s_v0_hw.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#ifndef _HGI2S_V0_HW_H
|
||||
#define _HGI2S_V0_HW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup IIS MODULE REGISTER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/***** CON Register *****/
|
||||
/*! Filter the RX data from IO
|
||||
*/
|
||||
#define LL_I2S_CON_RXDBSBPS(n) (((n)&0x01) << 14)
|
||||
/*! Filter the WSCLK clock from IO
|
||||
*/
|
||||
#define LL_I2S_CON_WSCLKDBSBPS(n) (((n)&0x01) << 13)
|
||||
/*! Filter the BCLK clock from IO
|
||||
*/
|
||||
#define LL_I2S_CON_BCLKDBSBPS(n) (((n)&0x01) << 12)
|
||||
/*! I2S work mode select
|
||||
*/
|
||||
#define LL_I2S_CON_MCLK_OE(n) (((n)&0x01) << 11)
|
||||
/*! I2S channel mode select
|
||||
*/
|
||||
#define LL_I2S_CON_OV_PEND_IE(n) (((n)&0x01) << 10)
|
||||
/*! I2S BCK clock polarity
|
||||
*/
|
||||
#define LL_I2S_CON_HF_PEND_IE(n) (((n)&0x01) << 9)
|
||||
/*! I2S WS clock polarity
|
||||
*/
|
||||
#define LL_I2S_CON_WORKMODE(n) (((n)&0x01) << 8)
|
||||
/*! sign extension function
|
||||
*/
|
||||
#define LL_I2S_CON_MONO(n) (((n)&0x03) << 6)
|
||||
/*! I2S mode select
|
||||
*/
|
||||
#define LL_I2S_CON_BCKPOL(n) (((n)&0x01) << 5)
|
||||
/*! I2S serial data format
|
||||
*/
|
||||
#define LL_I2S_CON_WSPOL(n) (((n)&0x01) << 4)
|
||||
/*! Receive channel select
|
||||
*/
|
||||
#define LL_I2S_CON_MODE(n) (((n)&0x01) << 3)
|
||||
/*! Transmit channel select
|
||||
*/
|
||||
#define LL_I2S_CON_FRMT(n) (((n)&0x03) << 1)
|
||||
/*! I2S enable
|
||||
*/
|
||||
#define LL_I2S_CON_ENABLE(n) (((n)&0x01) << 0)
|
||||
|
||||
|
||||
|
||||
/***** BIT_SET Register *****/
|
||||
/*! I2S bit set
|
||||
*/
|
||||
#define LL_I2S_BIT_SET_IISBIT(n) (((n)&0x1F) << 0)
|
||||
|
||||
|
||||
/***** BUAD Register *****/
|
||||
/*! I2S baud set
|
||||
*/
|
||||
#define LL_I2S_BAUD_SET_BUAD(n) (((n)&0x3F) << 0)
|
||||
|
||||
|
||||
/***** WSCON Register *****/
|
||||
/*! I2S wscon set
|
||||
*/
|
||||
#define LL_I2S_WSCON_SET_WSCON(n) (((n)&0x3F) << 0)
|
||||
|
||||
|
||||
/***** STA Register *****/
|
||||
/*! I2S DMA data over pending
|
||||
*/
|
||||
#define LL_I2S_STA_DMA_OV_PENGING(n) (((n)&0x01) << 5)
|
||||
/*! I2S DMA data half pending
|
||||
*/
|
||||
#define LL_I2S_STA_DMA_HF_PENGING(n) (((n)&0x01) << 4)
|
||||
/*! I2S transmit done pending
|
||||
*/
|
||||
#define LL_I2S_STA_DONE_PENGING(n) (((n)&0x01) << 3)
|
||||
/*! I2S work state pending
|
||||
*/
|
||||
#define LL_I2S_STA_WORK_STATE_PENGING(n) (((n)&0x01) << 2)
|
||||
/*! I2S fifo write full pending
|
||||
*/
|
||||
#define LL_I2S_STA_FIFO_WFULL_PENGING(n) (((n)&0x01) << 1)
|
||||
/*! I2S fifo read empty pending
|
||||
*/
|
||||
#define LL_I2S_STA_FIFO_REMPTY_PENGING(n) (((n)&0x01) << 0)
|
||||
|
||||
/***** STADR0 Register *****/
|
||||
/*! I2S DMA address config
|
||||
*/
|
||||
#define LL_I2S_STADR_DMA_ADDR0(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
/***** DMALEN Register *****/
|
||||
/*! I2S DMA len config
|
||||
*/
|
||||
#define LL_I2S_DMALEN_LEN(n) (((n)&0xFFFF) << 0)
|
||||
|
||||
|
||||
|
||||
/** @brief I2S register structure
|
||||
* @{
|
||||
*/
|
||||
struct hgi2s_v0_hw {
|
||||
__IO uint32_t CON;
|
||||
__IO uint32_t BIT_SET;
|
||||
__IO uint32_t BAUD;
|
||||
__IO uint32_t WS_CON;
|
||||
__IO uint32_t STA;
|
||||
__IO uint32_t DMA_STADR;
|
||||
__IO uint32_t RESERVE;
|
||||
__IO uint32_t DMA_LEN;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGI2S_V0_HW_H */
|
||||
834
sdk/driver/jpeg/hgjpg_v3.c
Normal file
834
sdk/driver/jpeg/hgjpg_v3.c
Normal file
@@ -0,0 +1,834 @@
|
||||
#include "sys_config.h"
|
||||
#include "tx_platform.h"
|
||||
#include "list.h"
|
||||
#include "dev.h"
|
||||
#include "typesdef.h"
|
||||
#include "lib/video/dvp/cmos_sensor/csi.h"
|
||||
#include "dev/csi/hgdvp.h"
|
||||
#include "devid.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/string.h"
|
||||
#include "dev/jpg/hgjpg.h"
|
||||
#include "lib/video/dvp/jpeg/jpg.h"
|
||||
#include "hal/jpeg.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/sleep.h"
|
||||
|
||||
//调用外部接口
|
||||
void driver_timer_add(int32_t (*func)(void *arg,uint32_t kick_time), void *arg);
|
||||
|
||||
struct hgjpg_hw
|
||||
{
|
||||
__IO uint32 CSR0;
|
||||
__IO uint32 CSR1;
|
||||
__IO uint32 CSR2;
|
||||
__IO uint32 CSR3;
|
||||
__IO uint32 DMA_CON;
|
||||
__IO uint32 DMA_CON1;
|
||||
__IO uint32 DMA_STA;
|
||||
__IO uint32 DMA_TADR0;
|
||||
__IO uint32 DMA_TADR1;
|
||||
__IO uint32 DMA_DLEN;
|
||||
__IO uint32 DMA_DHT_ADR;
|
||||
__IO uint32 DMA_DADR;
|
||||
__IO uint32 DMA_DTO;
|
||||
__IO uint32 DMA_SF_YADR;
|
||||
__IO uint32 DMA_SF_UADR;
|
||||
__IO uint32 DMA_SF_VADR;
|
||||
};
|
||||
|
||||
|
||||
struct hgjpg_table_hw
|
||||
{
|
||||
__IO uint32 DQT[32];
|
||||
};
|
||||
|
||||
struct hgjpg_huff_hw
|
||||
{
|
||||
__IO uint32_t HUFF[192];
|
||||
};
|
||||
|
||||
struct jpg_device *p_jpg_global[JPG_NUM];
|
||||
volatile uint8_t jpg_ready[JPG_NUM];
|
||||
|
||||
|
||||
volatile uint8_t jpg_oe_enable[JPG_NUM];
|
||||
volatile uint8_t jpg_oe_used[JPG_NUM];
|
||||
volatile uint8_t jpg_oe_ok[JPG_NUM];
|
||||
|
||||
extern volatile uint8 isp_ov_err;
|
||||
|
||||
|
||||
jpg_irq_hdl jpgirq_vector_table[JPG_NUM][JPG_IRQ_NUM];
|
||||
void * jpgirq_dev_table[JPG_NUM][JPG_IRQ_NUM];
|
||||
|
||||
void irq_jpg_enable(struct hgjpg_hw *p_jpg,uint8 mode,uint8 irq){
|
||||
if(mode){
|
||||
p_jpg->DMA_CON |= BIT(irq+13);
|
||||
}else{
|
||||
p_jpg->DMA_CON &= ~BIT(irq+13);
|
||||
}
|
||||
}
|
||||
|
||||
extern volatile uint8_t vpp_oe;
|
||||
void JPG_IRQHandler_action(void *p_jpg)
|
||||
{
|
||||
uint32 jpgr = 0;
|
||||
uint32 sta = 0;
|
||||
uint8_t jpg_err = 0;
|
||||
uint8 dec_err = 0;
|
||||
uint32 arg = 0;
|
||||
uint32 arg2 = 0;
|
||||
int8_t loop;
|
||||
struct hgjpg *jpg_hw;// = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw;// = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||||
uint8_t src_from;
|
||||
if(p_jpg_global[0]){
|
||||
jpg_hw = (struct hgjpg*)p_jpg_global[0];
|
||||
hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
sta = (hw->DMA_STA & ((hw->DMA_CON >> 13) &0x01f));
|
||||
src_from = (hw->DMA_CON& 0xE0)>>5;
|
||||
for(loop = JPG_IRQ_NUM-1;loop >= 0;loop--) {
|
||||
if(sta&BIT(loop)){
|
||||
if(jpg_hw->opened)
|
||||
{
|
||||
if(loop == DONE_IRQ){
|
||||
//_os_printf("--(%d)",SCHED->BW_STA_CNT);
|
||||
jpg_hw->addr_count = 0;
|
||||
arg = hw->DMA_DLEN;
|
||||
if(jpg_hw->deal_time != ((hw->DMA_STA>>16)&0xff)){
|
||||
arg2 = 1;
|
||||
}
|
||||
jpg_hw->deal_time = 0;
|
||||
}
|
||||
else if(loop == JPG_BUF_ERR){
|
||||
_os_printf(KERN_INFO"hw->DMA_STA0:%x\r\n",hw->DMA_STA);
|
||||
jpg_hw->addr_count = 0;
|
||||
arg = hw->DMA_DLEN;
|
||||
jpg_hw->deal_time = 0;
|
||||
}else if(loop == JPG_OUTBUF_FULL){
|
||||
jpg_hw->deal_time++;
|
||||
}
|
||||
|
||||
if(isp_ov_err && (jpg_hw->decode== 0 && (src_from == 0 || src_from == 1 || src_from == 3))){
|
||||
if(loop == DONE_IRQ){
|
||||
jpgirq_vector_table[0][JPG_BUF_ERR] (loop,(uint32)jpgirq_dev_table[0][JPG_BUF_ERR],arg,arg2);
|
||||
jpg_err = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//如果有错,就不再继续执行其他的中断
|
||||
if(jpg_err==0 && jpgirq_vector_table[0][loop] != NULL)
|
||||
jpgirq_vector_table[0][loop] (loop,(uint32)jpgirq_dev_table[0][loop],arg,arg2);
|
||||
|
||||
if(loop == JPG_BUF_ERR)
|
||||
{
|
||||
jpg_err = 1;
|
||||
}
|
||||
}
|
||||
hw->DMA_STA = BIT(loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(p_jpg_global[1]){
|
||||
jpg_hw = (struct hgjpg*)p_jpg_global[1];
|
||||
hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
sta = (hw->DMA_STA & ((hw->DMA_CON >> 13) &0x1f));
|
||||
src_from = (hw->DMA_CON& 0xE0)>>5;
|
||||
for(loop = JPG_IRQ_NUM-1;loop >= 0;loop--) {
|
||||
if(sta&BIT(loop)){
|
||||
if(jpg_hw->opened || jpg_hw->decode)
|
||||
{
|
||||
if(loop == DONE_IRQ){
|
||||
jpg_hw->addr_count = 0;
|
||||
arg = hw->DMA_DLEN;
|
||||
if(jpg_hw->deal_time != ((hw->DMA_STA>>16)&0xff)){
|
||||
arg2 = 1;
|
||||
}
|
||||
jpg_hw->deal_time = 0;
|
||||
jpg_hw->decode = 0;
|
||||
}
|
||||
else if(loop == JPG_BUF_ERR){
|
||||
_os_printf(KERN_INFO"hw->DMA_STA1:%x\r\n",hw->DMA_STA);
|
||||
jpg_hw->addr_count = 0;
|
||||
arg = hw->DMA_DLEN;
|
||||
jpg_hw->deal_time = 0;
|
||||
jpg_hw->decode = 0;
|
||||
if(hw->DMA_STA & BIT(8)){
|
||||
dec_err = 1;
|
||||
}
|
||||
}else if(loop == JPG_OUTBUF_FULL){
|
||||
jpg_hw->deal_time++;
|
||||
}
|
||||
if(isp_ov_err && (jpg_hw->decode== 0 && (src_from == 0 || src_from == 1 || src_from == 3))){
|
||||
if(loop == DONE_IRQ){
|
||||
jpgirq_vector_table[1][JPG_BUF_ERR] (loop,(uint32)jpgirq_dev_table[1][JPG_BUF_ERR],arg,arg2);
|
||||
jpg_err = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(jpgirq_vector_table[1][loop] != NULL)
|
||||
jpgirq_vector_table[1][loop] (loop,(uint32)jpgirq_dev_table[1][loop],arg,arg2);
|
||||
|
||||
|
||||
if(dec_err == 1){
|
||||
jpg_hw->decode = 0;
|
||||
hw->DMA_CON |= BIT(12); //复位
|
||||
__NOP();__NOP();__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
hw->DMA_STA = BIT(loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
int32 hgjpg_set_len(struct jpg_device *p_jpg,uint32 buflen,uint32 head_reserver){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
hw->DMA_CON |= ((buflen - head_reserver)<<16);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void jpg_table_init(struct hgjpg_hw *p_jpg,struct hgjpg_table_hw* p_jpg_dqt,struct hgjpg_huff_hw *p_jpg_huff,uint32 table_index){
|
||||
uint32 itk = 0;
|
||||
uint32 *ptable;
|
||||
ptable = (uint32*)quality_tab[table_index];
|
||||
for(itk = 0;itk <32;itk++){
|
||||
p_jpg_dqt->DQT[itk] = ptable[itk];
|
||||
}
|
||||
#if 0
|
||||
uint16 *huftbl;
|
||||
huftbl = (uint16_t*)htable;
|
||||
for(itk = 0;itk <384;itk=itk+2){
|
||||
p_jpg_huff->HUFF[itk/2] = (uint32)huftbl[itk]|(uint32)huftbl[itk+1]<<12;
|
||||
|
||||
}
|
||||
#endif
|
||||
p_jpg->DMA_DHT_ADR = (uint32)dhtable;
|
||||
}
|
||||
|
||||
static void jpg_huff_init(struct hgjpg* jpg)
|
||||
{
|
||||
struct hgjpg_huff_hw *p_jpg_huff = (struct hgjpg_huff_hw *)jpg->huf_hw;
|
||||
uint32 itk = 0;
|
||||
uint16 *huftbl;
|
||||
huftbl = (uint16_t*)htable;
|
||||
for(itk = 0;itk <384;itk=itk+2)
|
||||
{
|
||||
p_jpg_huff->HUFF[itk/2] = (uint32)huftbl[itk]|(uint32)huftbl[itk+1]<<12;
|
||||
}
|
||||
}
|
||||
|
||||
void jpg_csr_encode_config(struct hgjpg_hw *p_jpg,uint32 image_h,uint32 image_w){
|
||||
p_jpg->CSR1 = (image_h<<16)|BIT(2)|BIT(8);
|
||||
if((image_h%16) != 0)
|
||||
image_h = ((image_h/16)+1)*16;
|
||||
p_jpg->CSR2 = ((image_h * image_w) /256)-1;
|
||||
p_jpg->CSR3 = (image_w<<16)|(image_w/16 - 1);
|
||||
|
||||
}
|
||||
|
||||
int32 hgjpg_open(struct jpg_device *p_jpg){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
uint8 jpg_chose;
|
||||
|
||||
//fix psram read data lock bug
|
||||
//burst enable 0
|
||||
//1ms
|
||||
//burst enable 1
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
//hw->CSR1 = 0;
|
||||
uint32_t jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||||
(void)jpgr;
|
||||
}
|
||||
|
||||
//SCHED->BW_STA_CYCLE = 60000000;
|
||||
//SCHED->CTRL_CON |=BIT(1);
|
||||
//open之前先将pending清除(预防之前pengding有残留)
|
||||
hw->DMA_STA = hw->DMA_STA;
|
||||
jpg_hw->decode = 0;
|
||||
jpg_hw->opened = 1;
|
||||
jpg_ready[jpg_chose] = 1;
|
||||
hw->DMA_CON |= BIT(0); //enable jpg
|
||||
hw->DMA_CON1 |= BIT(5);
|
||||
//hw->CSR0 = 1;
|
||||
irq_enable(jpg_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t hgjpg_timer_close(void *arg,uint32_t kick_time)
|
||||
{
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)arg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
int32_t ret = 1;
|
||||
//代表jpg已经完成
|
||||
if(!(hw->DMA_STA&(0x7<<25)))
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
//超时也要退出
|
||||
if(os_jiffies() - kick_time > 1000)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
//关闭jpg
|
||||
if(!ret)
|
||||
{
|
||||
uint8_t jpg_chose = 0;
|
||||
uint32_t flag;
|
||||
flag = disable_irq();
|
||||
hw->DMA_CON &= ~(7<<5);
|
||||
hw->DMA_CON |= (SOFT_DATA <<5);
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
}
|
||||
enable_irq(flag);
|
||||
|
||||
|
||||
flag = disable_irq();
|
||||
hw->DMA_CON &= ~BIT(0); //disable jpg
|
||||
hw->DMA_STA = hw->DMA_STA;
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
hw->CSR1 = 0;
|
||||
uint32_t jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||||
(void)jpgr;
|
||||
}
|
||||
jpg_ready[jpg_chose] = 0;
|
||||
enable_irq(flag);
|
||||
jpg_hw->opened = 0;
|
||||
jpg_hw->decode = 0;
|
||||
jpg_hw->addr_count = 0;
|
||||
jpg_hw->jpg_run = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int32 hgjpg_close(struct jpg_device *p_jpg){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
uint8_t jpg_chose = 0;
|
||||
uint32_t flag;
|
||||
uint32_t in_disable_irq(void);
|
||||
if(!(__in_interrupt() || in_disable_irq()))
|
||||
{
|
||||
//在线程,jpg的close启动timer去操作
|
||||
driver_timer_add(hgjpg_timer_close,(void*)jpg_hw);
|
||||
}
|
||||
//在中断,则直接去关闭
|
||||
else
|
||||
{
|
||||
hw->DMA_CON &= ~(7<<5);
|
||||
hw->DMA_CON |= (SOFT_DATA <<5);
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
}
|
||||
|
||||
flag = disable_irq();
|
||||
hw->DMA_CON &= ~BIT(0); //disable jpg
|
||||
hw->DMA_STA = hw->DMA_STA;
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
//hw->CSR1 = 0;
|
||||
uint32_t jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||||
(void)jpgr;
|
||||
}
|
||||
jpg_ready[jpg_chose] = 0;
|
||||
enable_irq(flag);
|
||||
jpg_hw->opened = 0;
|
||||
jpg_hw->decode = 0;
|
||||
jpg_hw->addr_count = 0;
|
||||
jpg_hw->jpg_run = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 hgjpg_suspend(struct dev_obj *obj){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)obj;
|
||||
struct hgjpg_hw *hw;
|
||||
struct hgjpg_hw *hw_cfg;
|
||||
jpg_hw->cfg_backup = (uint32 *)os_malloc(sizeof(struct hgjpg_hw));
|
||||
//memcpy((uint8 *)p_jpg->cfg_backup,(uint8 *)jpg_hw->hw,sizeof(struct hgjpg_hw));
|
||||
hw_cfg = (struct hgjpg_hw*)jpg_hw->cfg_backup;
|
||||
hw = (struct hgjpg_hw*)jpg_hw->hw;
|
||||
hw_cfg->CSR0 = hw->CSR0;
|
||||
hw_cfg->CSR1 = hw->CSR1;
|
||||
hw_cfg->CSR2 = hw->CSR2;
|
||||
hw_cfg->CSR3 = hw->CSR3;
|
||||
hw_cfg->DMA_CON1= hw->DMA_CON1;
|
||||
hw_cfg->DMA_STA = hw->DMA_STA;
|
||||
hw_cfg->DMA_DHT_ADR = hw->DMA_DHT_ADR;
|
||||
hw_cfg->DMA_DADR= hw->DMA_DADR;
|
||||
hw_cfg->DMA_DTO = hw->DMA_DTO;
|
||||
hw_cfg->DMA_SF_YADR = hw->DMA_SF_YADR;
|
||||
hw_cfg->DMA_SF_UADR = hw->DMA_SF_UADR;
|
||||
hw_cfg->DMA_SF_VADR = hw->DMA_SF_VADR;
|
||||
hw_cfg->DMA_TADR0 = hw->DMA_TADR0;
|
||||
hw_cfg->DMA_TADR1 = hw->DMA_TADR1;
|
||||
hw_cfg->DMA_DLEN = hw->DMA_DLEN;
|
||||
hw_cfg->DMA_CON = hw->DMA_CON;
|
||||
irq_disable(jpg_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 hgjpg_resume(struct dev_obj *obj){
|
||||
uint32 jpgr = 0;
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)obj;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
struct hgjpg_hw *hw_cfg;
|
||||
struct hgjpg_table_hw *thw = (struct hgjpg_table_hw *)jpg_hw->thw;
|
||||
struct hgjpg_huff_hw *hufhw = (struct hgjpg_huff_hw *)jpg_hw->huf_hw;
|
||||
//memcpy((uint8 *)jpg_hw->hw,(uint8 *)p_jpg->cfg_backup,sizeof(struct hgjpg_hw));
|
||||
|
||||
|
||||
// SCHED->BW_STA_CYCLE = SYS_CLK;
|
||||
SYSCTRL->CPU1_CON1 &= ~BIT(17);
|
||||
// SCHED->CTRL_CON |=BIT(1);
|
||||
SYSCTRL->SYS_CON8 |= BIT(8); //960M enable
|
||||
SYSCTRL->SYS_CON14 &= ~(7<<29);
|
||||
SYSCTRL->SYS_CON14 |= (6<<29); //mjpeg_pll2x_divnp5 div 3
|
||||
SYSCTRL->SYS_CON14 |= BIT(28); //mjpeg_pll2x_divnp5 en
|
||||
SYSCTRL->CLK_CON6 &= ~(3<<30);
|
||||
SYSCTRL->CLK_CON6 |= (1<<30); //select mjpeg_pll2x_divnp5
|
||||
SYSCTRL->CLK_CON6 &= (~(7<<0)); //mjpeg 1div
|
||||
SYSCTRL->CPU1_CON0 |= BIT(0);
|
||||
SYSCTRL->CLK_CON3 |= BIT(14); //mjpg0 clk en
|
||||
SYSCTRL->CLK_CON4 |= BIT(0); //mjpg1 clk en
|
||||
SYSCTRL->SYS_CON7 &= ~BIT(10);
|
||||
SYSCTRL->SYS_CON7 |= BIT(10); //JPG0
|
||||
SYSCTRL->SYS_CON7 &= ~BIT(20);
|
||||
SYSCTRL->SYS_CON7 |= BIT(20); //JPG1
|
||||
jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||||
|
||||
|
||||
hw_cfg = (struct hgjpg_hw*)jpg_hw->cfg_backup;
|
||||
jpg_table_init(hw,thw,hufhw,0x01);
|
||||
hw->CSR0 = hw_cfg->CSR0;
|
||||
hw->CSR1 = hw_cfg->CSR1;
|
||||
hw->CSR2 = hw_cfg->CSR2;
|
||||
hw->CSR3 = hw_cfg->CSR3;
|
||||
hw->DMA_CON1= hw_cfg->DMA_CON1;
|
||||
hw->DMA_STA = hw_cfg->DMA_STA;
|
||||
hw->DMA_DHT_ADR = hw_cfg->DMA_DHT_ADR;
|
||||
hw->DMA_DADR= hw_cfg->DMA_DADR;
|
||||
hw->DMA_DTO = hw_cfg->DMA_DTO;
|
||||
hw->DMA_SF_YADR = hw_cfg->DMA_SF_YADR;
|
||||
hw->DMA_SF_UADR = hw_cfg->DMA_SF_UADR;
|
||||
hw->DMA_SF_VADR = hw_cfg->DMA_SF_VADR;
|
||||
hw->DMA_TADR0 = hw_cfg->DMA_TADR0;
|
||||
hw->DMA_TADR1 = hw_cfg->DMA_TADR1;
|
||||
hw->DMA_DLEN = hw_cfg->DMA_DLEN;
|
||||
hw->DMA_CON = hw_cfg->DMA_CON;
|
||||
jpgr = *(volatile uint32_t*)0x40005200;
|
||||
irq_enable(jpg_hw->irq_num);
|
||||
os_free(jpg_hw->cfg_backup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 hgjpg_init(struct jpg_device *p_jpg,uint32 table_index,uint32 qt){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
struct hgjpg_table_hw *thw = (struct hgjpg_table_hw *)jpg_hw->thw;
|
||||
struct hgjpg_huff_hw *hufhw = (struct hgjpg_huff_hw *)jpg_hw->huf_hw;
|
||||
hw->DMA_CON |= BIT(12); //复位
|
||||
__NOP();__NOP();__NOP();
|
||||
SYSCTRL->CLK_CON3 |= BIT(14);
|
||||
SYSCTRL->SYS_CON0 |= BIT(2); //
|
||||
jpg_table_init(hw,thw,hufhw,table_index);
|
||||
hw->DMA_CON = (qt<<1);
|
||||
jpg_hw->addr_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32 hgjpg_set_addr(struct jpg_device *p_jpg,uint32 param,uint32 buflen){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
uint8 jpg_chose;
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
}
|
||||
|
||||
if(jpg_hw->jpg_run == 0){
|
||||
//printf("#################hw:%X\n",hw);
|
||||
//os_printf("jpg_hw->addr_count:%d\n",jpg_hw->addr_count);
|
||||
//os_printf("jpg_ready[jpg_chose]:%d\t%d\n",jpg_ready[jpg_chose],jpg_chose);
|
||||
//os_printf("jpg_chose:%d\n",jpg_chose);
|
||||
jpg_hw->jpg_run = 1;
|
||||
jpg_hw->set_buf_len = 1;
|
||||
|
||||
}
|
||||
if(jpg_hw->addr_count%2){
|
||||
hw->DMA_TADR1 = param;
|
||||
}else{
|
||||
if(jpg_ready[jpg_chose]){
|
||||
|
||||
hw->DMA_TADR0 = param;
|
||||
//hw->DMA_CON1 &= ~BIT(5);
|
||||
hw->DMA_CON1 |= BIT(5);
|
||||
jpg_ready[jpg_chose] = 0;
|
||||
}else{
|
||||
hw->DMA_TADR0 = param;
|
||||
}
|
||||
}
|
||||
if(jpg_hw->set_buf_len){
|
||||
hw->DMA_CON |= ((buflen/4-1)<<20);
|
||||
jpg_hw->set_buf_len = 0;
|
||||
}
|
||||
jpg_hw->addr_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decode to scaler
|
||||
int32 hgjpg_decode(struct jpg_device *p_jpg,uint32 photo,uint32_t len){
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
if(hw->DMA_CON & BIT(0)){
|
||||
hw->DMA_CON &= ~BIT(0);
|
||||
}
|
||||
hw->DMA_CON &= ~(7<<5);
|
||||
hw->DMA_CON |= BIT(12); //复位
|
||||
__NOP();__NOP();__NOP();
|
||||
//hw->DMA_CON &= ~BIT(12);
|
||||
hw->CSR1 = BIT(3)|BIT(8);
|
||||
hw->DMA_DADR = photo;
|
||||
jpg_hw->decode = 1;
|
||||
|
||||
if (len % 4) {
|
||||
len = len + 4;
|
||||
}
|
||||
|
||||
//寄存器检查仅仅支持1M以下
|
||||
if(len != 0 && len < 0x100000){
|
||||
hw->DMA_DLEN = len; //需要word对齐
|
||||
hw->DMA_CON1 |= BIT(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
hw->DMA_CON1 &= ~BIT(1);
|
||||
}
|
||||
hw->DMA_CON &= ~(0xf<<1);
|
||||
hw->DMA_CON |= BIT(4);
|
||||
hw->DMA_CON |= BIT(0);
|
||||
irq_enable(jpg_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 hgjpg_ioctl(struct jpg_device *p_jpg,uint32 cmd,uint32 param1,uint32 param2){
|
||||
int32 ret_val = RET_OK;
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
struct hgjpg_table_hw *thw = (struct hgjpg_table_hw *)jpg_hw->thw;
|
||||
uint8 jpg_chose;
|
||||
uint32* dqt;
|
||||
uint32 itk;
|
||||
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
}
|
||||
|
||||
|
||||
switch(cmd){
|
||||
case JPG_IOCTL_CMD_IS_ONLINE:
|
||||
return jpg_hw->opened;
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_ADR:
|
||||
hgjpg_set_addr(p_jpg,param1,param2);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_QT:
|
||||
hw->DMA_CON &= ~(0xf<<1);
|
||||
hw->DMA_CON |= (param1<<1);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_SIZE:
|
||||
jpg_csr_encode_config(hw,param1,param2);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_UPDATE_QT:
|
||||
dqt = (uint32*)param1;
|
||||
for(itk = 0;itk <32;itk++){
|
||||
thw->DQT[itk] = dqt[itk];
|
||||
}
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_DECODE_TAG:
|
||||
if(param1){
|
||||
hw->DMA_CON |= BIT(8);
|
||||
}else{
|
||||
hw->DMA_CON &= ~BIT(8);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case JPG_IOCTL_CMD_OPEN_DBG:
|
||||
if(param1){
|
||||
hw->DMA_CON |= BIT(10);
|
||||
}else{
|
||||
hw->DMA_CON &= ~BIT(10);
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case JPG_IOCTL_CMD_SOFT_FRAME_START:
|
||||
hw->DMA_CON |= BIT(10);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SOFT_KICK:
|
||||
hw->DMA_CON |= BIT(9);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_SRC_FROM:
|
||||
hw->DMA_CON &= ~(7<<5);
|
||||
hw->DMA_CON |= (param1 <<5);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_HW_CHK:
|
||||
if(param1){
|
||||
hw->DMA_CON |= BIT(11);
|
||||
}else{
|
||||
hw->DMA_CON &= ~BIT(11);
|
||||
}
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_IS_IDLE:
|
||||
if(hw->DMA_STA&(0x7<<25)){
|
||||
ret_val = 0;
|
||||
}else{
|
||||
ret_val = 1;
|
||||
}
|
||||
break;
|
||||
case JPG_IOCTL_CMD_BUFF_INIT:
|
||||
if(param1 == 1){
|
||||
hw->DMA_CON1 |= BIT(5);
|
||||
}else{
|
||||
hw->DMA_CON1 &= ~BIT(5);
|
||||
}
|
||||
break;
|
||||
case JPG_IOCTL_CMD_VSYNC_DLY:
|
||||
if(param1 == 1){
|
||||
hw->DMA_CON1 |= BIT(4);
|
||||
}else{
|
||||
hw->DMA_CON1 &= ~BIT(4);
|
||||
}
|
||||
break;
|
||||
case JPG_IOCTL_CMD_SET_SOFT_Y:
|
||||
hw->DMA_SF_YADR = param1;
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_SOFT_UV:
|
||||
hw->DMA_SF_UADR = param1;
|
||||
hw->DMA_SF_VADR = param2;
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_TIMEOUT_CNT:
|
||||
hw->DMA_DTO = param1;
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_TIMEOUT_EN:
|
||||
hw->DMA_CON1 |= BIT(3);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_DECAUTO_RUN_EN:
|
||||
hw->DMA_CON1 |= BIT(2);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_DEC_LEN_CFG_EN:
|
||||
//SET this bit ,may set the dlen len reg, otherwise while auto dec until finish or timeout err happen
|
||||
if(param1){
|
||||
hw->DMA_CON1 |= BIT(1);
|
||||
}else{
|
||||
hw->DMA_CON1 &= ~BIT(1);
|
||||
}
|
||||
break;
|
||||
case JPG_IOCTL_CMD_DEC_FLUSH_EN:
|
||||
//set this bit,dec while run ,but not set data to memory,just check dec right or false
|
||||
if(param1){
|
||||
hw->DMA_CON1 |= BIT(0);
|
||||
}else{
|
||||
hw->DMA_CON1 &= ~BIT(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_CODEC_RESET:
|
||||
hw->DMA_CON |= BIT(12);
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_DLEN:
|
||||
hw->DMA_DLEN = param1;
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_READY:
|
||||
jpg_ready[jpg_chose] = 1;
|
||||
break;
|
||||
|
||||
case JPG_IOCTL_CMD_SET_OE_SELECT:
|
||||
if(param1 == 1){
|
||||
jpg_oe_enable[jpg_chose] = 1;
|
||||
jpg_oe_used[jpg_chose] = param2;
|
||||
}else{
|
||||
jpg_oe_enable[jpg_chose] = 0;
|
||||
}
|
||||
break;
|
||||
case JPG_IOCTL_CMD_SET_OE:
|
||||
jpg_oe_ok[jpg_chose] = param1;
|
||||
break;
|
||||
case JPG_IOCTL_CMD_GET_OE:
|
||||
if(jpg_oe_enable[jpg_chose] == 1){
|
||||
if(jpg_oe_ok[jpg_chose] == jpg_oe_used[jpg_chose]){
|
||||
ret_val = 1;
|
||||
}else{
|
||||
ret_val = 0;
|
||||
}
|
||||
}else{
|
||||
ret_val = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
int32 jpgirq_register(struct jpg_device *p_jpg, jpg_irq_hdl isr,uint32 irq_flag, uint32 irq_data)
|
||||
{
|
||||
uint8 jpg_chose;
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
uint32 irq_num = 0;
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
}
|
||||
p_jpg_global[jpg_chose] = p_jpg;
|
||||
request_irq(MJPEG01_IRQn, JPG_IRQHandler_action, NULL);
|
||||
if(irq_flag == JPG_IRQ_FLAG_JPG_DONE ){
|
||||
irq_num = DONE_IRQ;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_JPG_BUF_FULL ){
|
||||
irq_num = JPG_OUTBUF_FULL;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_ERROR ){
|
||||
irq_num = JPG_BUF_ERR;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_PIXEL_DONE ){
|
||||
irq_num = JPG_PIXEL_DONE;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_TIME_OUT){
|
||||
irq_num = JPG_TIME_OUT;
|
||||
}
|
||||
irq_jpg_enable(hw, 1, irq_num);
|
||||
|
||||
jpgirq_vector_table[jpg_chose][irq_num] = isr;
|
||||
jpgirq_dev_table[jpg_chose][irq_num] = (void *)irq_data;
|
||||
hw->DMA_STA |= BIT(irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 jpgirq_unregister(struct jpg_device *p_jpg,uint32 irq_flag){
|
||||
uint8 jpg_chose;
|
||||
struct hgjpg *jpg_hw = (struct hgjpg*)p_jpg;
|
||||
struct hgjpg_hw *hw = (struct hgjpg_hw *)jpg_hw->hw;
|
||||
uint32 irq_num = 0;
|
||||
if(hw == (void *)MJPEG0_BASE){
|
||||
jpg_chose = 0;
|
||||
}
|
||||
|
||||
if(hw == (void *)MJPEG1_BASE){
|
||||
jpg_chose = 1;
|
||||
}
|
||||
|
||||
if(irq_flag == JPG_IRQ_FLAG_JPG_DONE ){
|
||||
irq_num = DONE_IRQ;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_JPG_BUF_FULL ){
|
||||
irq_num = JPG_OUTBUF_FULL;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_ERROR ){
|
||||
irq_num = JPG_BUF_ERR;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_PIXEL_DONE ){
|
||||
irq_num = JPG_PIXEL_DONE;
|
||||
}else if(irq_flag == JPG_IRQ_FLAG_TIME_OUT){
|
||||
irq_num = JPG_TIME_OUT;
|
||||
}
|
||||
|
||||
irq_jpg_enable(hw, 0, irq_num);
|
||||
jpgirq_vector_table[jpg_chose][irq_num] = NULL;
|
||||
jpgirq_dev_table[jpg_chose][irq_num] = NULL;
|
||||
hw->DMA_STA |= BIT(irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct jpeg_hal_ops jpeg_ops = {
|
||||
.open = hgjpg_open,
|
||||
.close = hgjpg_close,
|
||||
.init = hgjpg_init,
|
||||
.decode = hgjpg_decode,
|
||||
.ioctl = hgjpg_ioctl,
|
||||
.request_irq = jpgirq_register,
|
||||
.release_irq = jpgirq_unregister,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hgjpg_suspend,
|
||||
.ops.resume = hgjpg_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
void hgjpg_attach(uint32 dev_id, struct hgjpg *jpg)
|
||||
{
|
||||
jpg->dev.dev.ops = (const struct devobj_ops *)&jpeg_ops;
|
||||
irq_disable(jpg->irq_num);
|
||||
dev_register(dev_id, (struct dev_obj *)jpg);
|
||||
jpg_huff_init(jpg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
227
sdk/driver/osd_enc/hgosd_enc.c
Normal file
227
sdk/driver/osd_enc/hgosd_enc.c
Normal file
@@ -0,0 +1,227 @@
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/irq.h"
|
||||
#include "devid.h"
|
||||
#include "dev/osd_enc/hgosd_enc.h"
|
||||
#include "osal/string.h"
|
||||
|
||||
struct hgosdenc_hw
|
||||
{
|
||||
__IO uint32 OSD_ENC_CON;
|
||||
__IO uint32 OSD_ENC_STA;
|
||||
__IO uint32 OSD_ENC_SADR;
|
||||
__IO uint32 OSD_ENC_TADR;
|
||||
__IO uint32 OSD_ENC_RLEN;
|
||||
__IO uint32 OSD_ENC_DLEN;
|
||||
__IO uint32 OSD_ENC_IDENT0;
|
||||
__IO uint32 OSD_ENC_IDENT1;
|
||||
__IO uint32 OSD_ENC_TRANS0;
|
||||
__IO uint32 OSD_ENC_TRANS1;
|
||||
};
|
||||
|
||||
static int32 hgosd_ioctl(struct osdenc_device *p_osd, enum osdenc_ioctl_cmd ioctl_cmd, uint32 param1, uint32 param2)
|
||||
{
|
||||
int32 ret_val = RET_OK;
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
uint32_t *p32;
|
||||
switch(ioctl_cmd){
|
||||
case OSD_IOCTL_TRAN_IDENT_TRANS:
|
||||
p32 = (uint32_t *)param1;
|
||||
hw->OSD_ENC_IDENT0 = p32[0];
|
||||
hw->OSD_ENC_IDENT1 = p32[1];
|
||||
hw->OSD_ENC_TRANS0 = p32[2];
|
||||
hw->OSD_ENC_TRANS1 = p32[3];
|
||||
break;
|
||||
|
||||
case OSD_IOCTL_ENC_ADR:
|
||||
hw->OSD_ENC_SADR = param1;
|
||||
hw->OSD_ENC_TADR = param2;
|
||||
break;
|
||||
|
||||
case OSD_IOCTL_SET_ENC_RLEN:
|
||||
hw->OSD_ENC_RLEN = ((param1/4 + 1)/2)*2 - 1; //word 偶对齐 -1
|
||||
break;
|
||||
|
||||
case OSD_IOCTL_SET_ENC_FORMAT:
|
||||
if(param1 == 1){
|
||||
hw->OSD_ENC_CON &= ~BIT(1); //565
|
||||
}else{
|
||||
hw->OSD_ENC_CON |= BIT(1); //888
|
||||
}
|
||||
break;
|
||||
|
||||
case OSD_IOCTL_GET_ENC_DLEN:
|
||||
return hw->OSD_ENC_DLEN*4;
|
||||
break;
|
||||
|
||||
case OSD_IOCTL_SET_ENC_RUN:
|
||||
hw->OSD_ENC_CON |= BIT(0);
|
||||
break;
|
||||
default:
|
||||
os_printf("NO OSD IOCTL:%d\r\n",ioctl_cmd);
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
osdenc_irq_hdl encirq_vector_table[ENC_IRQ_NUM];
|
||||
void * encirq_dev_table[ENC_IRQ_NUM];
|
||||
|
||||
void irq_osdenc_enable(struct osdenc_device *p_osd,uint8 mode,uint8 irq){
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
if(mode){
|
||||
hw->OSD_ENC_CON |= BIT(irq+2);
|
||||
}else{
|
||||
hw->OSD_ENC_CON &= ~BIT(irq+2);
|
||||
}
|
||||
}
|
||||
|
||||
void OSD_ENC_IRQHandler_action(void *p_osd){
|
||||
uint32 sta = 0;
|
||||
uint8 loop;
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
sta = hw->OSD_ENC_STA;
|
||||
for(loop = 0;loop < ENC_IRQ_NUM;loop++){
|
||||
if(sta&BIT(loop)){
|
||||
hw->OSD_ENC_STA = BIT(loop);
|
||||
if(encirq_vector_table[loop] != NULL)
|
||||
encirq_vector_table[loop] (loop,(uint32)encirq_dev_table[loop],0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 osd_enc_irq_register(struct osdenc_device *p_osd,uint32 irq, osdenc_irq_hdl isr, uint32 dev_id){
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
request_irq(osd_hw->irq_num, OSD_ENC_IRQHandler_action, p_osd);
|
||||
irq_osdenc_enable(p_osd, 1, irq);
|
||||
encirq_vector_table[irq] = isr;
|
||||
encirq_dev_table[irq] = (void*)dev_id;
|
||||
hw->OSD_ENC_STA |= BIT(irq);
|
||||
os_printf("osdencirq_register:%d %x %x\r\n",irq,(uint32)encirq_vector_table[irq],(uint32)isr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 osd_enc_irq_unregister(struct osdenc_device *p_osd,uint32 irq){
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
irq_osdenc_enable(p_osd, 0, irq);
|
||||
encirq_vector_table[irq] = NULL;
|
||||
encirq_dev_table[irq] = 0;
|
||||
hw->OSD_ENC_STA |= BIT(irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 hgosdenc_open(struct osdenc_device *p_osd){
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
//struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
#ifdef FPGA_SUPPORT
|
||||
SYSCTRL->SYS_CON0 |= BIT(12);
|
||||
#else
|
||||
sysctrl_osd_enc_clk_open();
|
||||
SYSCTRL->SYS_CON7 |= BIT(15);
|
||||
#endif
|
||||
irq_enable(osd_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 hgosdenc_close(struct osdenc_device *p_osd){
|
||||
struct hgosd *osd_hw = (struct hgosd*)p_osd;
|
||||
//struct hgosdenc_hw *hw = (struct hgosdenc_hw *)osd_hw->hw;
|
||||
sysctrl_osd_enc_clk_close();
|
||||
irq_disable(osd_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 hgosdenc_suspend(struct dev_obj *obj){
|
||||
struct hgosd *osd_hw = (struct hgosd*)obj;
|
||||
struct hgosdenc_hw *hw;
|
||||
struct hgosdenc_hw *hw_cfg;
|
||||
//确保已经被打开并且休眠过,直接返回
|
||||
if(!osd_hw->opened || osd_hw->dsleep)
|
||||
{
|
||||
return RET_OK;
|
||||
}
|
||||
osd_hw->dsleep = 1;
|
||||
osd_hw->cfg_backup = (uint32 *)os_malloc(sizeof(struct hgosdenc_hw));
|
||||
hw_cfg = (struct hgosdenc_hw*)osd_hw->cfg_backup;
|
||||
hw = (struct hgosdenc_hw*)osd_hw->hw;
|
||||
|
||||
hw_cfg->OSD_ENC_CON=hw->OSD_ENC_CON;
|
||||
hw_cfg->OSD_ENC_STA=hw->OSD_ENC_STA;
|
||||
hw_cfg->OSD_ENC_SADR=hw->OSD_ENC_SADR;
|
||||
hw_cfg->OSD_ENC_TADR=hw->OSD_ENC_TADR;
|
||||
hw_cfg->OSD_ENC_RLEN=hw->OSD_ENC_RLEN;
|
||||
hw_cfg->OSD_ENC_DLEN=hw->OSD_ENC_DLEN;
|
||||
hw_cfg->OSD_ENC_IDENT0=hw->OSD_ENC_IDENT0;
|
||||
hw_cfg->OSD_ENC_IDENT1=hw->OSD_ENC_IDENT1;
|
||||
hw_cfg->OSD_ENC_TRANS0=hw->OSD_ENC_TRANS0;
|
||||
hw_cfg->OSD_ENC_TRANS1=hw->OSD_ENC_TRANS1;
|
||||
|
||||
irq_disable(osd_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 hgosdenc_resume(struct dev_obj *obj){
|
||||
struct hgosd *osd_hw = (struct hgosd*)obj;
|
||||
struct hgosdenc_hw *hw;
|
||||
struct hgosdenc_hw *hw_cfg;
|
||||
//如果已经被打开并且没有休眠过,直接返回
|
||||
if(!osd_hw->opened || !osd_hw->dsleep)
|
||||
{
|
||||
return RET_OK;
|
||||
}
|
||||
osd_hw->dsleep = 0;
|
||||
hw_cfg = (struct hgosdenc_hw*)osd_hw->cfg_backup;
|
||||
hw = (struct hgosdenc_hw*)osd_hw->hw;
|
||||
|
||||
hw->OSD_ENC_CON=hw_cfg->OSD_ENC_CON;
|
||||
hw->OSD_ENC_STA=hw_cfg->OSD_ENC_STA;
|
||||
hw->OSD_ENC_SADR=hw_cfg->OSD_ENC_SADR;
|
||||
hw->OSD_ENC_TADR=hw_cfg->OSD_ENC_TADR;
|
||||
hw->OSD_ENC_RLEN=hw_cfg->OSD_ENC_RLEN;
|
||||
hw->OSD_ENC_DLEN=hw_cfg->OSD_ENC_DLEN;
|
||||
hw->OSD_ENC_IDENT0=hw_cfg->OSD_ENC_IDENT0;
|
||||
hw->OSD_ENC_IDENT1=hw_cfg->OSD_ENC_IDENT1;
|
||||
hw->OSD_ENC_TRANS0=hw_cfg->OSD_ENC_TRANS0;
|
||||
hw->OSD_ENC_TRANS1=hw_cfg->OSD_ENC_TRANS1;
|
||||
|
||||
irq_enable(osd_hw->irq_num);
|
||||
os_free(osd_hw->cfg_backup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct osdenc_hal_ops dev_ops = {
|
||||
.open = hgosdenc_open,
|
||||
.close = hgosdenc_close,
|
||||
.ioctl = hgosd_ioctl,
|
||||
.request_irq = osd_enc_irq_register,
|
||||
.release_irq = osd_enc_irq_unregister,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hgosdenc_suspend,
|
||||
.ops.resume = hgosdenc_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
int32 hgosdenc_attach(uint32 dev_id, struct hgosd *hgosd){
|
||||
hgosd->opened = 0;
|
||||
hgosd->use_dma = 0;
|
||||
hgosd->irq_hdl = NULL;
|
||||
hgosd->irq_data = 0;
|
||||
hgosd->dev.dev.ops = (const struct devobj_ops *)&dev_ops;
|
||||
irq_disable(hgosd->irq_num);
|
||||
dev_register(dev_id, (struct dev_obj *)hgosd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
373
sdk/driver/pwm/hgpwm_v0.c
Normal file
373
sdk/driver/pwm/hgpwm_v0.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/**
|
||||
* @file hgpwm_v0.c
|
||||
* @author bxd
|
||||
* @brief pwm
|
||||
* @version
|
||||
* TXW80X; TXW81X
|
||||
* @date 2023-08-02
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "errno.h"
|
||||
#include "dev.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/string.h"
|
||||
#include "hal/timer_device.h"
|
||||
#include "hal/pwm.h"
|
||||
#include "dev/pwm/hgpwm_v0.h"
|
||||
|
||||
/**********************************************************************************/
|
||||
/* LOW LAYER FUNCTION */
|
||||
/**********************************************************************************/
|
||||
|
||||
static int32 hgpwm_v0_switch_hal_pwm_channel(enum pwm_channel param) {
|
||||
|
||||
switch (param) {
|
||||
case (PWM_CHANNEL_0):
|
||||
return 0;
|
||||
break;
|
||||
case (PWM_CHANNEL_1):
|
||||
return 1;
|
||||
break;
|
||||
case (PWM_CHANNEL_2):
|
||||
return 2;
|
||||
break;
|
||||
case (PWM_CHANNEL_3):
|
||||
return 3;
|
||||
break;
|
||||
case (PWM_CHANNEL_4):
|
||||
return 4;
|
||||
break;
|
||||
case (PWM_CHANNEL_5):
|
||||
return 5;
|
||||
break;
|
||||
// case (PWM_CHANNEL_6):
|
||||
// return 6;
|
||||
// break;
|
||||
// case (PWM_CHANNEL_7):
|
||||
// return 7;
|
||||
// break;
|
||||
// case (PWM_CHANNEL_8):
|
||||
// return 8;
|
||||
// break;
|
||||
// case (PWM_CHANNEL_9):
|
||||
// return 9;
|
||||
// break;
|
||||
// case (PWM_CHANNEL_10):
|
||||
// return 10;
|
||||
// break;
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_config(struct hgpwm_v0 *dev, enum pwm_channel channel, struct hgpwm_v0_config *config) {
|
||||
|
||||
struct hgpwm_v0_config *p_config = config;
|
||||
uint32 channel_to_reg = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the config struct pointer */
|
||||
if (!p_config) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_to_reg = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_to_reg) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make sure the timer is attached */
|
||||
if ((dev->channel[channel_to_reg])) {
|
||||
ret_val = timer_device_ioctl((struct timer_device *)dev->channel[channel_to_reg], HGPWM_V0_FUNC_CMD_MASK, (uint32)p_config, 0);
|
||||
} else {
|
||||
ret_val = RET_ERR;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**********************************************************************************/
|
||||
/* ATTCH FUNCTION */
|
||||
/**********************************************************************************/
|
||||
|
||||
static int32 hgpwm_v0_init(struct pwm_device *pwm, enum pwm_channel channel, uint32 period_sysclkpd_cnt, uint32 h_duty_sysclkpd_cnt) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 channel_num = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_num = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make busy status */
|
||||
if (dev->opened[channel_num]) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* config pwm */
|
||||
config.period = period_sysclkpd_cnt;
|
||||
config.duty = h_duty_sysclkpd_cnt;
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_INIT;
|
||||
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
dev->opened[channel_num] = 1;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_deinit(struct pwm_device *pwm, enum pwm_channel channel) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 channel_num = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_num = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make busy status */
|
||||
if (!(dev->opened[channel_num])) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_DEINIT;
|
||||
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
dev->opened[channel_num] = 0;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_start(struct pwm_device *pwm, enum pwm_channel channel) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 channel_num = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_num = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make busy status */
|
||||
if (!(dev->opened[channel_num])) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_START;
|
||||
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_stop(struct pwm_device *pwm, enum pwm_channel channel) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 channel_num = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_num = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make busy status */
|
||||
if (!(dev->opened[channel_num])) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_STOP;
|
||||
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SLEEP
|
||||
static int32 hgpwm_v0_suspend(struct pwm_device *pwm, enum pwm_channel channel)
|
||||
{
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 channel_num = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_num = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make busy status */
|
||||
if (!(dev->opened[channel_num])) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_SUSPEND;
|
||||
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_resume(struct pwm_device *pwm, enum pwm_channel channel)
|
||||
{
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 channel_num = 0;
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
/* Make sure the channel */
|
||||
channel_num = hgpwm_v0_switch_hal_pwm_channel(channel);
|
||||
if ((-1) == channel_num) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make busy status */
|
||||
if (!(dev->opened[channel_num])) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_RESUME;
|
||||
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32 hgpwm_v0_ioctl(struct pwm_device *pwm, enum pwm_channel channel, enum pwm_ioctl_cmd ioctl_cmd, uint32 param1, uint32 param2) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
int32 ret_val = RET_OK;
|
||||
|
||||
switch (ioctl_cmd) {
|
||||
case (PWM_IOCTL_CMD_SET_PERIOD_DUTY):
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_IOCTL_SET_PERIOD_DUTY;
|
||||
config.period = param1;
|
||||
config.duty = param2;
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
case (PWM_IOCTL_CMD_SET_SINGLE_INCREAM):
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_IOCTL_SET_SINGLE_INCREAM;
|
||||
config.period = param1;
|
||||
config.duty = param2;
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
case (PWM_IOCTL_CMD_SET_INCREAM_DECREASE):
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_IOCTL_SET_INCREAM_DECREASE;
|
||||
config.period = param1;
|
||||
config.duty = param2;
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
case (PWM_IOCTL_CMD_SET_PRESCALER):
|
||||
/*!
|
||||
* @brief: set prescaler
|
||||
* @param1: prescaler
|
||||
* @param2: NULL
|
||||
*/
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_IOCTL_SET_PRESCALER;
|
||||
config.param1 = param1;
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
case (PWM_IOCTL_CMD_SET_PERIOD_DUTY_IMMEDIATELY):
|
||||
/*!
|
||||
* @brief: set period and duty immediately
|
||||
* @param1: period
|
||||
* @param2: duty
|
||||
*/
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_IOCTL_SET_PERIOD_DUTY_IMMEDIATELY;
|
||||
config.period = param1;
|
||||
config.duty = param2;
|
||||
ret_val = hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_request_irq(struct pwm_device *pwm, enum pwm_channel channel, enum pwm_irq_flag irq_flag, pwm_irq_hdl irq_hdl, uint32 data) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
|
||||
switch (irq_flag) {
|
||||
case (PWM_IRQ_FLAG_COMPARE):
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_REQUEST_IRQ_COMPARE;
|
||||
config.irq_hdl = irq_hdl;
|
||||
config.irq_data = data;
|
||||
hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
case (PWM_IRQ_FLAG_PERIOD):
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_REQUEST_IRQ_PERIOD;
|
||||
config.irq_hdl = irq_hdl;
|
||||
config.irq_data = data;
|
||||
hgpwm_v0_config(dev, channel, &config);
|
||||
break;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hgpwm_v0_release_irq(struct pwm_device *pwm, enum pwm_channel channel) {
|
||||
|
||||
struct hgpwm_v0 *dev = (struct hgpwm_v0 *)pwm;
|
||||
struct hgpwm_v0_config config = {0};
|
||||
|
||||
config.func_cmd = HGPWM_V0_FUNC_CMD_RELEASE_IRQ;
|
||||
config.irq_data = 0;
|
||||
config.irq_hdl = NULL;
|
||||
|
||||
hgpwm_v0_config(dev, channel, &config);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const struct pwm_hal_ops pwm_v0_ops = {
|
||||
.init = hgpwm_v0_init,
|
||||
.deinit = hgpwm_v0_deinit,
|
||||
.start = hgpwm_v0_start,
|
||||
.stop = hgpwm_v0_stop,
|
||||
.ioctl = hgpwm_v0_ioctl,
|
||||
.request_irq = hgpwm_v0_request_irq,
|
||||
.release_irq = hgpwm_v0_release_irq,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = NULL,//hgpwm_v0_suspend,
|
||||
.ops.resume = NULL,//hgpwm_v0_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
int32 hgpwm_v0_attach(uint32 dev_id, struct hgpwm_v0 *pwm) {
|
||||
|
||||
uint32 i = 0;
|
||||
for (i=0; i<HGPWM_MAX_PWM_CHANNEL; i++) {
|
||||
pwm->opened[i] = 0;
|
||||
}
|
||||
pwm->dev.dev.ops = (const struct devobj_ops *)&pwm_v0_ops;
|
||||
dev_register(dev_id, (struct dev_obj *)pwm);
|
||||
return RET_OK;
|
||||
}
|
||||
1118
sdk/driver/scale/hgscale_v3.c
Normal file
1118
sdk/driver/scale/hgscale_v3.c
Normal file
File diff suppressed because it is too large
Load Diff
449
sdk/driver/sha/hgsha_v1.c
Normal file
449
sdk/driver/sha/hgsha_v1.c
Normal file
@@ -0,0 +1,449 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hgsha.c
|
||||
* @author HUGE-IC Application Team
|
||||
* @version V1.0.0
|
||||
* @date
|
||||
* @brief sha256
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2019 HUGE-IC</center></h2>
|
||||
*
|
||||
*
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#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 "osal/string.h"
|
||||
#include "osal/sleep.h"
|
||||
|
||||
#include "dev/sha/hgsha_v1.h"
|
||||
#include "hgsha_v1_hw.h"
|
||||
#include "hal/sha.h"
|
||||
|
||||
#if 1
|
||||
#define SHA_PRINTF(fmt, arg...) printf(fmt, ##arg)
|
||||
#else
|
||||
#define SHA_PRINTF(fmt, arg...)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SHA1_INIT = BIT(3) | BIT(1),
|
||||
SHA1_UPDATE = BIT(3),
|
||||
SHA1_FINISH = BIT(3) | BIT(2),
|
||||
SHA2_INIT = BIT(1),
|
||||
SHA2_UPDATE = 0,
|
||||
SHA2_FINISH = BIT(2),
|
||||
|
||||
SHA_INTR_EN = BIT(0),
|
||||
} SHA_HWMODE;
|
||||
|
||||
|
||||
#define SHA_NONBLOCK (0x1000)
|
||||
|
||||
/********************************
|
||||
*
|
||||
* LOW LAYER FUNCTION AREA
|
||||
*
|
||||
* *****************************/
|
||||
static inline void ll_sha_get_result_big_endian(struct hgsha_v1_hw *hw, uint8 *buf)
|
||||
{
|
||||
volatile uint32_t *tmp = (uint32_t *) & (hw->SHA_RESULT0);
|
||||
uint32_t tmp_dat = 0;
|
||||
|
||||
for (uint32_t i = 0; i < 8; i++, tmp++) {
|
||||
tmp_dat = *tmp;
|
||||
*buf++ = (tmp_dat ) & 0xFF;
|
||||
*buf++ = (tmp_dat >> 8) & 0xFF;
|
||||
*buf++ = (tmp_dat >> 16) & 0xFF;
|
||||
*buf++ = (tmp_dat >> 24) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ll_sha_get_result_little_endian(struct hgsha_v1_hw *hw, uint8 *buf)
|
||||
{
|
||||
volatile uint32_t *tmp = (uint32_t *) & (hw->SHA_RESULT0);
|
||||
uint32_t tmp_dat = 0;
|
||||
|
||||
for (uint32_t i = 0; i < 8; i++, tmp++) {
|
||||
tmp_dat = *tmp;
|
||||
*buf++ = (tmp_dat >> 24) & 0xFF;
|
||||
*buf++ = (tmp_dat >> 16) & 0xFF;
|
||||
*buf++ = (tmp_dat >> 8) & 0xFF;
|
||||
*buf++ = (tmp_dat ) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
static void ll_sha_calc(struct hgsha_v1_hw *sha, uint8_t *buf, uint16_t len, SHA_HWMODE mode)
|
||||
{
|
||||
sha->SHA_STADDR = (uint32)buf;
|
||||
sha->SHA_BYTELEN = len;
|
||||
sha->SHA_PENDING = 1;
|
||||
sha->SHA_CONFIG = mode;
|
||||
sha->SHA_START = 1;
|
||||
// while(!sha->SHA_PENDING);
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
*
|
||||
* DRIVE LAYER FUNCTION AREA
|
||||
*
|
||||
* *****************************/
|
||||
|
||||
static void hgsha_irq_handle(void *args)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)args;
|
||||
struct hgsha_v1_hw *sha_reg = (struct hgsha_v1_hw *)sha->hw;
|
||||
|
||||
sha_reg->SHA_PENDING = 1;
|
||||
|
||||
os_sema_up(&sha->done);
|
||||
if (sha->irq_func) {
|
||||
sha->irq_func(sha->irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t hgsha_v1_request_irq(struct sha_dev *dev, void * irq_handle, void *args)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
sha->irq_func = args;
|
||||
sha->irq_data = irq_handle;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int hgsha_v1_release_irq(struct sha_dev *dev)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
sha->irq_func = NULL;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int hgsha_v1_transform(struct sha_dev *dev, struct sha_req *req)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
struct hgsha_v1_hw *hw = (struct hgsha_v1_hw *)sha->hw;
|
||||
int ret = 0;
|
||||
uint8_t *buf = req->input;
|
||||
uint32_t blocks = req->len / 64;
|
||||
uint32_t stas = 0;
|
||||
SHA_HWMODE mode = 0;
|
||||
if (os_mutex_lock(&sha->lock, 4000)) {
|
||||
printf("sha get mutex failure\r\n");
|
||||
return RET_ERR;
|
||||
}
|
||||
switch (req->type) {
|
||||
case T_SHA1:
|
||||
stas = 5 * 4;
|
||||
mode = SHA1_UPDATE;
|
||||
break;
|
||||
case T_SHA256:
|
||||
stas = 8 * 4;
|
||||
mode = SHA2_UPDATE;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
mode |= SHA_INTR_EN;
|
||||
|
||||
memcpy((void*)&hw->SHA_RESULT0, req->state, stas);
|
||||
|
||||
sys_dcache_clean_range_unaligned((void*)req->input, req->len);
|
||||
os_sema_eat(&sha->done);
|
||||
for (int bs = 512;bs>8;bs/=2) {
|
||||
for (;blocks>=bs;) {
|
||||
ll_sha_calc(hw, buf, bs * 64, mode);
|
||||
buf += bs * 64;
|
||||
blocks -= bs;
|
||||
ret |= !os_sema_down(&sha->done, 8000);
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks) {
|
||||
uint64_t tick = os_jiffies();
|
||||
mode &= ~SHA_INTR_EN;
|
||||
ll_sha_calc(hw, buf, blocks * 64, mode);
|
||||
while(!hw->SHA_PENDING)
|
||||
{
|
||||
if (os_jiffies()-tick >= 8000) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(req->state, (void*)&hw->SHA_RESULT0, stas);
|
||||
os_mutex_unlock(&sha->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __sha_init(struct sha_dev *dev, struct sha_ctx * ctx)
|
||||
{
|
||||
if (ctx->type == T_SHA1) {
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
ctx->state[4] = 0xC3D2E1F0;
|
||||
} else {
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
ctx->dlen = 0;
|
||||
ctx->bit_len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __sha_update(struct sha_dev *sha, struct sha_ctx *ctx, uint8_t *buf, uint32_t len)
|
||||
{
|
||||
struct sha_req req = {
|
||||
.state = ctx->state,
|
||||
.type = ctx->type,
|
||||
};
|
||||
|
||||
if (ctx->dlen) {
|
||||
if (ctx->dlen + len >= 64) {
|
||||
memcpy(&ctx->buf[ctx->dlen], buf, 64 - ctx->dlen);
|
||||
buf += 64 - ctx->dlen;
|
||||
len -= 64 - ctx->dlen;
|
||||
req.input = ctx->buf;
|
||||
req.len = 64;
|
||||
hgsha_v1_transform(sha, &req);
|
||||
ctx->bit_len += req.len * 8;
|
||||
ctx->dlen = 0;
|
||||
} else {
|
||||
memcpy(&ctx->buf[ctx->dlen], buf, len);
|
||||
ctx->dlen += len;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 512; i != 0; i /= 2) {
|
||||
while (len / 64 >= i) {
|
||||
req.input = buf;
|
||||
req.len = i * 64;
|
||||
hgsha_v1_transform(sha, &req);
|
||||
ctx->bit_len += req.len * 8;
|
||||
buf += i * 64;
|
||||
len -= i * 64;
|
||||
}
|
||||
}
|
||||
if (len) {
|
||||
memcpy(ctx->buf, buf, len);
|
||||
ctx->dlen = len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __sha_final(struct sha_dev *sha, struct sha_ctx *ctx, uint8_t *hash)
|
||||
{
|
||||
struct sha_req req = {
|
||||
.state = ctx->state,
|
||||
.type = ctx->type,
|
||||
.input = ctx->buf,
|
||||
.len = 64,
|
||||
};
|
||||
// Pad whatever data is left in the buffer.
|
||||
int i = ctx->dlen;
|
||||
if (ctx->dlen < 56) {
|
||||
ctx->buf[i++] = 0x80;
|
||||
while (i < 56)
|
||||
ctx->buf[i++] = 0x00;
|
||||
} else {
|
||||
ctx->buf[i++] = 0x80;
|
||||
while (i < 64)
|
||||
ctx->buf[i++] = 0x00;
|
||||
hgsha_v1_transform(sha, &req);
|
||||
memset(ctx->buf, 0, 56);
|
||||
}
|
||||
|
||||
// Append to the padding the total message's length in bits and transform.
|
||||
ctx->bit_len += ctx->dlen * 8;
|
||||
ctx->buf[63] = ctx->bit_len;
|
||||
ctx->buf[62] = ctx->bit_len >> 8;
|
||||
ctx->buf[61] = ctx->bit_len >> 16;
|
||||
ctx->buf[60] = ctx->bit_len >> 24;
|
||||
ctx->buf[59] = ctx->bit_len >> 32;
|
||||
ctx->buf[58] = ctx->bit_len >> 40;
|
||||
ctx->buf[57] = ctx->bit_len >> 48;
|
||||
ctx->buf[56] = ctx->bit_len >> 56;
|
||||
hgsha_v1_transform(sha, &req);
|
||||
|
||||
// Since this implementation uses little endian uint8_t ordering and SHA uses big endian,
|
||||
// reverse all the bytes when copying the final state to the output hash.
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
|
||||
if (ctx->type == T_SHA256) {
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hgsha_v1_init(struct sha_dev *dev, SHA_TYPE type)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
sha->ctx.type = type;
|
||||
sha->ctx.bit_len = 0;
|
||||
sha->ctx.dlen = 0;
|
||||
__sha_init(dev, sha->pctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 hgsha_v1_update(struct sha_dev *dev, uint8 *input, uint32 len)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
return __sha_update(dev, sha->pctx, input, len);
|
||||
}
|
||||
|
||||
static int32 hgsha_v1_final(struct sha_dev *dev, uint8 *output)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
return __sha_final(dev, sha->pctx, output);
|
||||
}
|
||||
|
||||
static int32 hgsha_v1_ioctl(struct sha_dev *dev, uint32 cmd, uint32 param1, uint32 param2)
|
||||
{
|
||||
struct hgsha_v1 *sha = (struct hgsha_v1 *)dev;
|
||||
|
||||
switch (cmd) {
|
||||
case SHA_IOCTL_CMD_START:
|
||||
os_mutex_lock(&sha->lock, osWaitForever);
|
||||
break;
|
||||
case SHA_IOCTL_CMD_END:
|
||||
os_mutex_unlock(&sha->lock);
|
||||
break;
|
||||
case SHA_IOCTL_CMD_RESET:
|
||||
break;
|
||||
case SHA_IOCTL_GET_CTX:
|
||||
*((struct sha_ctx*)param1) = sha->ctx;
|
||||
break;
|
||||
case SHA_IOCTL_PUT_CTX:
|
||||
sha->ctx = *((struct sha_ctx*)param1);
|
||||
break;
|
||||
case SHA_IOCTL_RELOAD_CTX:
|
||||
sha->pctx = (struct sha_ctx*)param1;
|
||||
break;
|
||||
default:
|
||||
return RET_ERR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void hg_sha_test_printf(struct sha_dev *dev)
|
||||
{
|
||||
uint8_t src[64];
|
||||
uint32_t rsum = 0;
|
||||
uint32_t state[8] = {
|
||||
0x12345678, 0x66225544, 0x11447788, 0x22441597,
|
||||
0x22441597, 0x11447788, 0x66225544, 0x12345678
|
||||
};
|
||||
for (int i = 0;i<64;i++)
|
||||
src[i] = i;
|
||||
struct sha_req req = {
|
||||
.type = T_SHA256,
|
||||
.input = src,
|
||||
.state = state,
|
||||
.len = 64,
|
||||
};
|
||||
hgsha_v1_transform(dev, &req);
|
||||
for (int i = 0;i<8;i++)
|
||||
rsum += state[i];
|
||||
|
||||
_os_printf("sha test: %x\r\n", rsum);
|
||||
if (rsum != 0x4a635c1c) {
|
||||
_os_printf("sha lp err\r\n");
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SLEEP
|
||||
// #define HGSHA_SLEEP_TEST(dev) hg_sha_test_printf(dev)
|
||||
#define HGSHA_SLEEP_TEST(dev)
|
||||
static int32 hgsha_v1_suspend(struct sha_dev *dev)
|
||||
{
|
||||
struct hgsha_v1 *sha =(struct hgsha_v1 *)dev;
|
||||
struct hgsha_v1_hw *sha_reg = sha->hw;
|
||||
HGSHA_SLEEP_TEST(dev);
|
||||
if(os_mutex_lock(&sha->lock, 80000)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
irq_disable(sha->irq_num);
|
||||
sysctrl_sha_clk_close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 hgsha_v1_resume(struct sha_dev *dev)
|
||||
{
|
||||
struct hgsha_v1 *sha =(struct hgsha_v1 *)dev;
|
||||
struct hgsha_v1_hw *hw = (struct hgsha_v1_hw *)sha->hw;
|
||||
os_mutex_unlock(&sha->lock);
|
||||
sysctrl_sha_clk_open();
|
||||
sysctrl_sha_reset();
|
||||
hw->SHA_PENDING |= 1;
|
||||
irq_enable(sha->irq_num);
|
||||
HGSHA_SLEEP_TEST(dev);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct sha_hal_ops sha_v1_ops = {
|
||||
.init = hgsha_v1_init,
|
||||
.update = hgsha_v1_update,
|
||||
.final = hgsha_v1_final,
|
||||
.xform = hgsha_v1_transform,
|
||||
.ioctl = hgsha_v1_ioctl,
|
||||
.requset_irq = hgsha_v1_request_irq,
|
||||
.release_irq = hgsha_v1_release_irq,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = (int32 (*)(struct dev_obj *obj))hgsha_v1_suspend,
|
||||
.ops.resume = (int32 (*)(struct dev_obj *obj))hgsha_v1_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
__init int32_t hgsha_v1_attach(uint32_t dev_id, struct hgsha_v1 *sha)
|
||||
{
|
||||
sha->dev.dev.ops = (const struct devobj_ops *)&sha_v1_ops;
|
||||
struct hgsha_v1_hw *hw = (struct hgsha_v1_hw *)sha->hw;
|
||||
|
||||
//clear pending
|
||||
hw->SHA_PENDING |= 1;
|
||||
sha->irq_func = NULL;
|
||||
sha->flags = 0;
|
||||
sha->pctx = &sha->ctx;
|
||||
|
||||
os_mutex_init(&sha->lock);
|
||||
os_sema_init(&sha->done, 0);
|
||||
|
||||
request_irq(sha->irq_num, hgsha_irq_handle, sha);
|
||||
irq_enable(sha->irq_num);
|
||||
|
||||
dev_register(dev_id, (struct dev_obj *)sha);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
23
sdk/driver/sha/hgsha_v1_hw.h
Normal file
23
sdk/driver/sha/hgsha_v1_hw.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef _HGSHA_V0_HW_H_
|
||||
#define _HGSHA_V0_HW_H_
|
||||
|
||||
#include "typesdef.h"
|
||||
|
||||
struct hgsha_v1_hw {
|
||||
__IO uint32 SHA_START;
|
||||
__IO uint32 SHA_BYTELEN;
|
||||
__IO uint32 SHA_CONFIG;
|
||||
__IO uint32 SHA_PENDING;
|
||||
__IO uint32 SHA_STADDR;
|
||||
uint32 reserved[3];
|
||||
__IO uint32 SHA_RESULT0;
|
||||
__IO uint32 SHA_RESULT1;
|
||||
__IO uint32 SHA_RESULT2;
|
||||
__IO uint32 SHA_RESULT3;
|
||||
__IO uint32 SHA_RESULT4;
|
||||
__IO uint32 SHA_RESULT5;
|
||||
__IO uint32 SHA_RESULT6;
|
||||
__IO uint32 SHA_RESULT7;
|
||||
};
|
||||
|
||||
#endif
|
||||
711
sdk/driver/spi/hgcqspi_hw.h
Normal file
711
sdk/driver/spi/hgcqspi_hw.h
Normal file
@@ -0,0 +1,711 @@
|
||||
#ifndef _HGCQSPI_HW_H_
|
||||
#define _HGCQSPI_HW_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief SPI register structure
|
||||
* @{
|
||||
*/
|
||||
struct hgcqspi_hw {
|
||||
__IO uint32 CONFIG; //0x00
|
||||
__IO uint32 DEV_RDINSTR_CONFIG; //0x04
|
||||
__IO uint32 DEV_WRINSTR_CONFIG; //0x08
|
||||
__IO uint32 DEV_DELAY; //0x0c
|
||||
__IO uint32 READ_DATA_CAPTURE; //0x10
|
||||
__IO uint32 DEV_SIZE_CONFIG; //0x14
|
||||
__IO uint32 SRAM_PARTITION; //0x18
|
||||
__IO uint32 IND_AHB_TRIGGER; //0x1c
|
||||
__IO uint32 PERIPH_CFG; //0x20
|
||||
__IO uint32 REMAP_ADD; //0x24
|
||||
__IO uint32 MODE_BIT; //0x28
|
||||
__IO uint32 SRAM_FILL_LEVEL; //0x2c
|
||||
__IO uint32 TX_THRESH; //0x30
|
||||
__IO uint32 RX_THRESH; //0x34
|
||||
__IO uint32 WRITE_COMP_CTRL; //0x38
|
||||
__IO uint32 MAX_NO_OF_POLLS; //0x3c
|
||||
__IO uint32 INT_STATUS; //0x40
|
||||
__IO uint32 INT_MASK; //0x44
|
||||
uint32 RESERVED0[2];
|
||||
__IO uint32 WRITE_PROT_L; //0x50
|
||||
__IO uint32 WRITE_PROT_U; //0x54
|
||||
__IO uint32 WRITE_PROT_CTRL; //0x58
|
||||
uint32 RESERVED1[1];
|
||||
__IO uint32 IND_RD_XFER_CTRL; //0x60
|
||||
__IO uint32 IND_RD_XFER_WMARK; //0x64
|
||||
__IO uint32 IND_RD_XFER_START_ADD; //0x68
|
||||
__IO uint32 IND_RD_XFER_NUM_BYTES; //0x6c
|
||||
__IO uint32 IND_WR_XFER_CTRL; //0x70
|
||||
__IO uint32 IND_WR_XFER_WMARK; //0x74
|
||||
__IO uint32 IND_WR_XFER_START_ADD; //0x78
|
||||
__IO uint32 IND_WR_XFER_NUM_BYTES; //0x7c
|
||||
__IO uint32 IND_AHB_TRIGGER_RANGE; //0x80
|
||||
uint32 RESERVED2[2];
|
||||
__IO uint32 FLASH_CMD_CTRL_MEM; //0x8C
|
||||
__IO uint32 FLASH_CMD_CTRL; //0x90
|
||||
__IO uint32 FLASH_CMD_ADD; //0x94
|
||||
uint32 RESERVED3[2];
|
||||
__IO uint32 FLASH_CMD_RDATA_L; //0xa0
|
||||
__IO uint32 FLASH_CMD_RDATA_U; //0xa4
|
||||
__IO uint32 FLASH_CMD_WDATA_L; //0xa8
|
||||
__IO uint32 FLASH_CMD_WDATA_U; //0xac
|
||||
__IO uint32 FLASH_STATUS; //0xb0
|
||||
__IO uint32 PHY_CONFIG; //0xb4
|
||||
__IO uint32 PHY_DLL_MASTER_CONFIG; //0xb8
|
||||
__IO uint32 DLL_OBSERVABLE_L; //0xbc
|
||||
__IO uint32 DLL_OBSERVABLE_U; //0xc0
|
||||
uint32 RESERVED4[5];
|
||||
__IO uint32 NEW_ADD_CONFIG0; //d8
|
||||
__IO uint32 NEW_ADD_CONFIG1; //dc
|
||||
__IO uint32 OPCODE_EXT_L; //E0
|
||||
__IO uint32 OPCODE_EXT_U; //E4
|
||||
__IO uint32 READ_DATA_CAPTURE_EXT; //0xE8
|
||||
__IO uint32 WRITE_PROT_CTRL_EXT; //0xEC
|
||||
__IO uint32 DEV_RDINSTR_CONFIG_CS1; //0xF0
|
||||
__IO uint32 DEV_WRINSTR_CONFIG_CS1; //0xF4
|
||||
__IO uint32 MONITOR; //0xF8, for OSPI
|
||||
__IO uint32 MODULE_ID; //0xfc
|
||||
};
|
||||
|
||||
|
||||
/** @addtogroup SPI MODULE REGISTER
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define CQSPI_NAME "cadence-qspi"
|
||||
#define CQSPI_MAX_CHIPSELECT 1//16
|
||||
#define CQSPI_AHB_TRIG_ADDR (0x18000000)
|
||||
|
||||
/* Operation timeout value */
|
||||
#define CQSPI_TIMEOUT_MS 500
|
||||
#define CQSPI_READ_TIMEOUT_MS 10
|
||||
|
||||
/* Instruction type */
|
||||
#define CQSPI_INST_TYPE_SINGLE 0
|
||||
#define CQSPI_INST_TYPE_DUAL 1
|
||||
#define CQSPI_INST_TYPE_QUAD 2
|
||||
|
||||
#define CQSPI_DUMMY_CLKS_PER_BYTE 8
|
||||
#define CQSPI_DUMMY_BYTES_MAX 4
|
||||
#define CQSPI_DUMMY_CLKS_MAX 31
|
||||
|
||||
#define CQSPI_STIG_DATA_LEN_MAX 8
|
||||
|
||||
/* Register map */
|
||||
#define CQSPI_REG_CONFIG 0x00
|
||||
#define CQSPI_REG_CONFIG_ENABLE_MASK BIT(0)
|
||||
#define CQSPI_REG_CONFIG_DECODE_MASK BIT(9)
|
||||
#define CQSPI_REG_CONFIG_CHIPSELECT_LSB 10
|
||||
#define CQSPI_REG_CONFIG_DMA_MASK BIT(15)
|
||||
#define CQSPI_REG_CONFIG_BAUD_LSB 19
|
||||
#define CQSPI_REG_CONFIG_IDLE_LSB 31
|
||||
#define CQSPI_REG_CONFIG_CHIPSELECT_MASK 0xF
|
||||
#define CQSPI_REG_CONFIG_BAUD_MASK 0xF
|
||||
|
||||
#define CQSPI_REG_RD_INSTR 0x04
|
||||
#define CQSPI_REG_RD_INSTR_OPCODE_LSB 0
|
||||
#define CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB 8
|
||||
#define CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB 12
|
||||
#define CQSPI_REG_RD_INSTR_TYPE_DATA_LSB 16
|
||||
#define CQSPI_REG_RD_INSTR_MODE_EN_LSB 20
|
||||
#define CQSPI_REG_RD_INSTR_DUMMY_LSB 24
|
||||
#define CQSPI_REG_RD_INSTR_TYPE_INSTR_MASK 0x3
|
||||
#define CQSPI_REG_RD_INSTR_TYPE_ADDR_MASK 0x3
|
||||
#define CQSPI_REG_RD_INSTR_TYPE_DATA_MASK 0x3
|
||||
#define CQSPI_REG_RD_INSTR_DUMMY_MASK 0x1F
|
||||
|
||||
#define CQSPI_REG_WR_INSTR 0x08
|
||||
#define CQSPI_REG_WR_INSTR_OPCODE_LSB 0
|
||||
#define CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB 12
|
||||
#define CQSPI_REG_WR_INSTR_TYPE_DATA_LSB 16
|
||||
|
||||
#define CQSPI_REG_DELAY 0x0C
|
||||
#define CQSPI_REG_DELAY_TSLCH_LSB 0
|
||||
#define CQSPI_REG_DELAY_TCHSH_LSB 8
|
||||
#define CQSPI_REG_DELAY_TSD2D_LSB 16
|
||||
#define CQSPI_REG_DELAY_TSHSL_LSB 24
|
||||
#define CQSPI_REG_DELAY_TSLCH_MASK 0xFF
|
||||
#define CQSPI_REG_DELAY_TCHSH_MASK 0xFF
|
||||
#define CQSPI_REG_DELAY_TSD2D_MASK 0xFF
|
||||
#define CQSPI_REG_DELAY_TSHSL_MASK 0xFF
|
||||
|
||||
#define CQSPI_REG_READCAPTURE 0x10
|
||||
#define CQSPI_REG_READCAPTURE_BYPASS_LSB 0
|
||||
#define CQSPI_REG_READCAPTURE_DELAY_LSB 1
|
||||
#define CQSPI_REG_READCAPTURE_DELAY_MASK 0xF
|
||||
|
||||
#define CQSPI_REG_SIZE 0x14
|
||||
#define CQSPI_REG_SIZE_ADDRESS_LSB 0
|
||||
#define CQSPI_REG_SIZE_PAGE_LSB 4
|
||||
#define CQSPI_REG_SIZE_BLOCK_LSB 16
|
||||
#define CQSPI_REG_SIZE_ADDRESS_MASK 0xF
|
||||
#define CQSPI_REG_SIZE_PAGE_MASK 0xFFF
|
||||
#define CQSPI_REG_SIZE_BLOCK_MASK 0x3F
|
||||
|
||||
#define CQSPI_REG_SRAMPARTITION 0x18
|
||||
#define CQSPI_REG_INDIRECTTRIGGER 0x1C
|
||||
|
||||
#define CQSPI_REG_DMA 0x20
|
||||
#define CQSPI_REG_DMA_SINGLE_LSB 0
|
||||
#define CQSPI_REG_DMA_BURST_LSB 8
|
||||
#define CQSPI_REG_DMA_SINGLE_MASK 0xFF
|
||||
#define CQSPI_REG_DMA_BURST_MASK 0xFF
|
||||
|
||||
#define CQSPI_REG_REMAP 0x24
|
||||
#define CQSPI_REG_MODE_BIT 0x28
|
||||
|
||||
#define CQSPI_REG_SDRAMLEVEL 0x2C
|
||||
#define CQSPI_REG_SDRAMLEVEL_RD_LSB 0
|
||||
#define CQSPI_REG_SDRAMLEVEL_WR_LSB 16
|
||||
#define CQSPI_REG_SDRAMLEVEL_RD_MASK 0xFFFF
|
||||
#define CQSPI_REG_SDRAMLEVEL_WR_MASK 0xFFFF
|
||||
|
||||
#define CQSPI_REG_IRQSTATUS 0x40
|
||||
#define CQSPI_REG_IRQMASK 0x44
|
||||
|
||||
#define CQSPI_REG_INDIRECTRD 0x60
|
||||
#define CQSPI_REG_INDIRECTRD_START_MASK BIT(0)
|
||||
#define CQSPI_REG_INDIRECTRD_CANCEL_MASK BIT(1)
|
||||
#define CQSPI_REG_INDIRECTRD_DONE_MASK BIT(5)
|
||||
|
||||
#define CQSPI_REG_INDIRECTRDWATERMARK 0x64
|
||||
#define CQSPI_REG_INDIRECTRDSTARTADDR 0x68
|
||||
#define CQSPI_REG_INDIRECTRDBYTES 0x6C
|
||||
|
||||
#define CQSPI_REG_CMDCTRL 0x90
|
||||
#define CQSPI_REG_CMDCTRL_EXECUTE_MASK BIT(0)
|
||||
#define CQSPI_REG_CMDCTRL_INPROGRESS_MASK BIT(1)
|
||||
#define CQSPI_REG_CMDCTRL_WR_BYTES_LSB 12
|
||||
#define CQSPI_REG_CMDCTRL_WR_EN_LSB 15
|
||||
#define CQSPI_REG_CMDCTRL_ADD_BYTES_LSB 16
|
||||
#define CQSPI_REG_CMDCTRL_ADDR_EN_LSB 19
|
||||
#define CQSPI_REG_CMDCTRL_RD_BYTES_LSB 20
|
||||
#define CQSPI_REG_CMDCTRL_RD_EN_LSB 23
|
||||
#define CQSPI_REG_CMDCTRL_OPCODE_LSB 24
|
||||
#define CQSPI_REG_CMDCTRL_WR_BYTES_MASK 0x7
|
||||
#define CQSPI_REG_CMDCTRL_ADD_BYTES_MASK 0x3
|
||||
#define CQSPI_REG_CMDCTRL_RD_BYTES_MASK 0x7
|
||||
|
||||
#define CQSPI_REG_INDIRECTWR 0x70
|
||||
#define CQSPI_REG_INDIRECTWR_START_MASK BIT(0)
|
||||
#define CQSPI_REG_INDIRECTWR_CANCEL_MASK BIT(1)
|
||||
#define CQSPI_REG_INDIRECTWR_DONE_MASK BIT(5)
|
||||
|
||||
#define CQSPI_REG_INDIRECTWRWATERMARK 0x74
|
||||
#define CQSPI_REG_INDIRECTWRSTARTADDR 0x78
|
||||
#define CQSPI_REG_INDIRECTWRBYTES 0x7C
|
||||
|
||||
#define CQSPI_REG_CMDADDRESS 0x94
|
||||
#define CQSPI_REG_CMDREADDATALOWER 0xA0
|
||||
#define CQSPI_REG_CMDREADDATAUPPER 0xA4
|
||||
#define CQSPI_REG_CMDWRITEDATALOWER 0xA8
|
||||
#define CQSPI_REG_CMDWRITEDATAUPPER 0xAC
|
||||
|
||||
/* Interrupt status bits */
|
||||
#define CQSPI_REG_IRQ_MODE_ERR BIT(0)
|
||||
#define CQSPI_REG_IRQ_UNDERFLOW BIT(1)
|
||||
#define CQSPI_REG_IRQ_IND_COMP BIT(2)
|
||||
#define CQSPI_REG_IRQ_IND_RD_REJECT BIT(3)
|
||||
#define CQSPI_REG_IRQ_WR_PROTECTED_ERR BIT(4)
|
||||
#define CQSPI_REG_IRQ_ILLEGAL_AHB_ERR BIT(5)
|
||||
#define CQSPI_REG_IRQ_WATERMARK BIT(6)
|
||||
#define CQSPI_REG_IRQ_IND_SRAM_FULL BIT(12)
|
||||
|
||||
#define CQSPI_IRQ_MASK_RD (CQSPI_REG_IRQ_WATERMARK | \
|
||||
CQSPI_REG_IRQ_IND_SRAM_FULL | \
|
||||
CQSPI_REG_IRQ_IND_COMP)
|
||||
|
||||
#define CQSPI_IRQ_MASK_WR (CQSPI_REG_IRQ_IND_COMP | \
|
||||
CQSPI_REG_IRQ_WATERMARK | \
|
||||
CQSPI_REG_IRQ_UNDERFLOW)
|
||||
|
||||
#define CQSPI_IRQ_STATUS_MASK 0x1FFFF
|
||||
|
||||
|
||||
/*
|
||||
* Note on opcode nomenclature: some opcodes have a format like
|
||||
* SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
|
||||
* of I/O lines used for the opcode, address, and data (respectively). The
|
||||
* FUNCTION has an optional suffix of '4', to represent an opcode which
|
||||
* requires a 4-byte (32-bit) address.
|
||||
*/
|
||||
|
||||
/* Flash opcodes. */
|
||||
#define SPINOR_OP_WREN 0x06 /* Write enable */
|
||||
#define SPINOR_OP_RDSR 0x05 /* Read status register */
|
||||
#define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */
|
||||
#define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */
|
||||
#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */
|
||||
#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */
|
||||
#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */
|
||||
#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
|
||||
#define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */
|
||||
#define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */
|
||||
#define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */
|
||||
#define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */
|
||||
#define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */
|
||||
#define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */
|
||||
#define SPINOR_OP_RDCR 0x35 /* Read configuration register */
|
||||
#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */
|
||||
|
||||
/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
|
||||
#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */
|
||||
#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
|
||||
#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */
|
||||
#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
|
||||
#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
|
||||
#define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */
|
||||
|
||||
/* Used for SST flashes only. */
|
||||
#define SPINOR_OP_BP 0x02 /* Byte program */
|
||||
#define SPINOR_OP_WRDI 0x04 /* Write disable */
|
||||
#define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */
|
||||
|
||||
/* Used for Macronix and Winbond flashes. */
|
||||
#define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */
|
||||
#define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */
|
||||
|
||||
/* Used for Spansion flashes only. */
|
||||
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
|
||||
|
||||
/* Used for Micron flashes only. */
|
||||
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
|
||||
#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
|
||||
|
||||
/* Status Register bits. */
|
||||
#define SR_WIP BIT(0) /* Write in progress */
|
||||
#define SR_WEL BIT(1) /* Write enable latch */
|
||||
/* meaning of other SR_* bits may differ between vendors */
|
||||
#define SR_BP0 BIT(2) /* Block protect 0 */
|
||||
#define SR_BP1 BIT(3) /* Block protect 1 */
|
||||
#define SR_BP2 BIT(4) /* Block protect 2 */
|
||||
#define SR_TB BIT(5) /* Top/Bottom protect */
|
||||
#define SR_SRWD BIT(7) /* SR write protect */
|
||||
|
||||
#define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */
|
||||
|
||||
/* Enhanced Volatile Configuration Register bits */
|
||||
#define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */
|
||||
|
||||
/* Flag Status Register bits */
|
||||
#define FSR_READY BIT(7)
|
||||
|
||||
/* Configuration Register bits. */
|
||||
#define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */
|
||||
|
||||
enum qspi_dev_size {
|
||||
QSPI_DEV_SIZE_8MB,
|
||||
QSPI_DEV_SIZE_16MB,
|
||||
QSPI_DEV_SIZE_32MB,
|
||||
QSPI_DEV_SIZE_4MB,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief ll_qspi_enable
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->CONFIG |= CQSPI_REG_CONFIG_ENABLE_MASK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ll_qspi_disable
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->CONFIG &= ~CQSPI_REG_CONFIG_ENABLE_MASK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ll_qspi_cs_sel
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param cs :cs select [0:3]
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_cs_sel(struct hgcqspi_hw *p_qspi, uint8 cs)
|
||||
{
|
||||
p_qspi->CONFIG = (p_qspi->CONFIG & ~(CQSPI_REG_CONFIG_CHIPSELECT_MASK << CQSPI_REG_CONFIG_CHIPSELECT_LSB)) |
|
||||
((~(BIT(cs)) & CQSPI_REG_CONFIG_CHIPSELECT_MASK) << CQSPI_REG_CONFIG_CHIPSELECT_LSB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_ahb_decoder_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->CONFIG |= BIT(23);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_device_size(struct hgcqspi_hw *p_qspi, uint8 dev_index, enum qspi_dev_size dev_size)
|
||||
{
|
||||
uint32 dev_size_reg = p_qspi->DEV_SIZE_CONFIG;
|
||||
|
||||
dev_size_reg &= ~((BIT(22)|BIT(21)) << (dev_index*2));
|
||||
dev_size_reg |= (dev_size << (21 + dev_index*2));
|
||||
|
||||
p_qspi->DEV_SIZE_CONFIG = dev_size_reg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_page_size(struct hgcqspi_hw *p_qspi, uint32 page_size)
|
||||
{
|
||||
uint32 dev_size_reg = p_qspi->DEV_SIZE_CONFIG;
|
||||
|
||||
dev_size_reg &= 0xFFFF000F;
|
||||
dev_size_reg |= (page_size & 0x0FFF) << 4;
|
||||
|
||||
p_qspi->DEV_SIZE_CONFIG = dev_size_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param size : blocksiez = power(2, size)
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_block_size(struct hgcqspi_hw *p_qspi, uint32 size)
|
||||
{
|
||||
uint32 dev_size_reg = p_qspi->DEV_SIZE_CONFIG;
|
||||
|
||||
dev_size_reg &= 0xFFE0FFFF;
|
||||
dev_size_reg |= (size & 0x01F) << 16;
|
||||
|
||||
p_qspi->DEV_SIZE_CONFIG = dev_size_reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_ahb_decoder_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->CONFIG &= ~(BIT(23));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ll_qspi_set_clk
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param clk_hz :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_clk(struct hgcqspi_hw *p_qspi, uint32 clk_hz)
|
||||
{
|
||||
uint32 div;
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
/* Recalculate the baudrate divisor based on QSPI specification. */
|
||||
#if 1//FPGA
|
||||
div = DIV_ROUND_UP(96000000, 2 * clk_hz) - 1;
|
||||
#else
|
||||
/* fill this : sys_clock_cfg.syspll_clk */
|
||||
div = DIV_ROUND_UP(384000000, 2 * clk_hz) - 1;
|
||||
#endif
|
||||
/* avoid qspi div2 bug */
|
||||
if (0 == div) div = 1;
|
||||
|
||||
p_qspi->CONFIG = (p_qspi->CONFIG & ~(CQSPI_REG_CONFIG_BAUD_MASK << CQSPI_REG_CONFIG_BAUD_LSB)) |
|
||||
((div & CQSPI_REG_CONFIG_BAUD_MASK) << CQSPI_REG_CONFIG_BAUD_LSB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ll_qspi_is_idle
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE bool ll_qspi_is_idle(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
return (p_qspi->CONFIG & BIT(31)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ll_qspi_is_cmd_done
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE bool ll_qspi_is_cmd_done(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
return (p_qspi->FLASH_CMD_CTRL & BIT(1)) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_wel_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->DEV_WRINSTR_CONFIG &= ~(BIT(8));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_wel_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->DEV_WRINSTR_CONFIG |= BIT(8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE bool ll_qspi_is_wel_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
return (p_qspi->DEV_WRINSTR_CONFIG & BIT(8)) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_poll_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->WRITE_COMP_CTRL &= ~(BIT(14));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_poll_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->WRITE_COMP_CTRL |= BIT(14);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE bool ll_qspi_is_poll_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
return (p_qspi->WRITE_COMP_CTRL & BIT(14)) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param width : 0/1/2 for data width 1/2/4
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_rd_attr(struct hgcqspi_hw *p_qspi,
|
||||
uint8 cmd,
|
||||
uint8 cmd_width,
|
||||
uint8 addr_width,
|
||||
uint8 dat_width,
|
||||
uint8 dummys,
|
||||
uint8 ddr_en)
|
||||
{
|
||||
p_qspi->DEV_RDINSTR_CONFIG = ((dummys & 0x1F) << 24) |
|
||||
((dat_width & 0x3) << 16) |
|
||||
((addr_width & 0x3) << 12) |
|
||||
((ddr_en & 0x1) << 10) |
|
||||
((cmd_width & 0x3) << 8) |
|
||||
cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi :QSPI register structure pointer
|
||||
* @param width : 0/1/2 for data width 1/2/4
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_wr_attr(struct hgcqspi_hw *p_qspi,
|
||||
uint8 cmd,
|
||||
uint8 cmd_width,
|
||||
uint8 addr_width,
|
||||
uint8 dat_width,
|
||||
uint8 dummys,
|
||||
uint8 wel_disable)
|
||||
{
|
||||
p_qspi->DEV_WRINSTR_CONFIG = ((dummys & 0x1F) << 24) |
|
||||
((dat_width & 0x3) << 16) |
|
||||
((addr_width & 0x3) << 12) |
|
||||
((wel_disable & 0x1) << 8) |
|
||||
cmd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param width :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_clk_mode(struct hgcqspi_hw *p_qspi, uint8 clock_mode)
|
||||
{
|
||||
p_qspi->CONFIG = (p_qspi->CONFIG & ~(BIT(1)|BIT(2))) | ((clock_mode & 0x3) << 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_set_sample_dalay(struct hgcqspi_hw *p_qspi, uint8 delay_ref_clk)
|
||||
{
|
||||
delay_ref_clk &= 0xF;
|
||||
p_qspi->DEV_DELAY = (p_qspi->DEV_DELAY & ~(0xFUL<<1)) | ((delay_ref_clk) << 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_remap_enable(struct hgcqspi_hw *p_qspi, uint32 offset)
|
||||
{
|
||||
while(!ll_qspi_is_idle(p_qspi));
|
||||
p_qspi->REMAP_ADD = offset;
|
||||
p_qspi->CONFIG |= (BIT(16));
|
||||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||||
while(!ll_qspi_is_idle(p_qspi));
|
||||
//csi_dcache_invalid();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_remap_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
while(!ll_qspi_is_idle(p_qspi));
|
||||
p_qspi->CONFIG &= ~(BIT(16));
|
||||
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
||||
while(!ll_qspi_is_idle(p_qspi));
|
||||
//csi_dcache_invalid();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_dac_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->CONFIG |= (BIT(7));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_dac_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->CONFIG &= ~(BIT(7));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_cs_fix_enable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->WRITE_PROT_CTRL |= (BIT(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param delay_ref_clk : the delay_ref_clk less than divor is better
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void ll_qspi_cs_fix_disable(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
p_qspi->WRITE_PROT_CTRL &= ~(BIT(3));
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32 ll_qspi_is_xip_mode(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
return (p_qspi->CONFIG & (BIT(17)|BIT(18))) ? 1:0;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32 ll_qspi_is_dtr_mode(struct hgcqspi_hw *p_qspi)
|
||||
{
|
||||
return (p_qspi->DEV_RDINSTR_CONFIG & BIT(10)) ? 1:0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief hg_qspi_set_encrypt_disable_range
|
||||
* @param p_qspi : QSPI register structure pointer
|
||||
* @param index : rang 0/1
|
||||
* @param st_addr_1k :
|
||||
* @param end_addr_1k :
|
||||
* @retval none
|
||||
*/
|
||||
__STATIC_INLINE void hg_qspi_set_encrypt_disable_range(struct hgcqspi_hw *p_qspi, uint8 index, uint32 st_addr_1k, uint32 end_addr_1k)
|
||||
{
|
||||
uint32 reg = (st_addr_1k & 0x7FFF) | ((end_addr_1k & 0x7FFF) << 16);
|
||||
SYSCTRL_REG_OPT(
|
||||
if (index) {
|
||||
SYSCTRL->QSPI_ENCDEC_CON1 = reg;
|
||||
} else {
|
||||
SYSCTRL->QSPI_ENCDEC_CON0 = (SYSCTRL->QSPI_ENCDEC_CON0 & BIT(31)) | reg;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
enum hgcqspi_flags {
|
||||
hgcqspi_flags_suspend,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGCQSPI_H_ */
|
||||
|
||||
259
sdk/driver/spi/hgspi_v1_hw.h
Normal file
259
sdk/driver/spi/hgspi_v1_hw.h
Normal file
@@ -0,0 +1,259 @@
|
||||
#ifndef _HGSPI_V1_HW_H_
|
||||
#define _HGSPI_V1_HW_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup SPI MODULE REGISTER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/***** CON0(for SPI) Register *****/
|
||||
/*! SPI slave read status done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_WRONGCMD_IE_EN (1UL << 25)
|
||||
/*! SPI slave read status done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_WIREMODE_IE_EN (1UL << 24)
|
||||
/*! SPI slave read status done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_RDSTATUS_IE_EN (1UL << 23)
|
||||
/*! SPI slave read data done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_RDDATA_IE_EN (1UL << 22)
|
||||
/*! SPI slave write data done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_WRDATA_IE_EN (1UL << 21)
|
||||
/*! SPI slave state enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_STATE_EN (1UL << 20)
|
||||
/*! SPI frame size
|
||||
*/
|
||||
#define LL_SPI_CON0_FRAME_SIZE(n) (((n)&0x3F) << 14)
|
||||
/*! Get SPI frame size
|
||||
*/
|
||||
#define LL_SPI_CON0_GET_FRAME_SIZE(n) (((n)>>14) & 0x3F)
|
||||
/*! SPI slave CS(NSS) rising edge interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_NSS_POS_IE_EN (1UL << 13)
|
||||
/*! SPI CS(NSS) pin enable
|
||||
*/
|
||||
#define LL_SPI_CON0_NSS_PIN_EN (1UL << 12)
|
||||
/*! SPI CS(NSS) output high
|
||||
* @note Only valid in SPI master mode
|
||||
*/
|
||||
#define LL_SPI_CON0_NSS_HIGH (1UL << 11)
|
||||
|
||||
/*! Input data synchronization enable in SPI slave mode
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_SYNC_EN (1UL << 7)
|
||||
/*! Input data synchronization enable in SPI master mode
|
||||
*/
|
||||
#define LL_SPI_CON0_MASTER_SYNC_EN (1UL << 6)
|
||||
/*! The SPI transfers data from the low bit
|
||||
*/
|
||||
#define LL_SPI_CON0_LSB_FIRST (1UL << 4)
|
||||
/*! SPI wire mode
|
||||
*/
|
||||
#define LL_SPI_CON0_WIRE_MODE(n) (((n)&0x03) << 2)
|
||||
/*! Get SPI wire mode
|
||||
*/
|
||||
#define LL_SPI_CON0_WIRE_MODE_GET(n) (((n)>>2) & 0x03)
|
||||
/*! SPI mode
|
||||
*/
|
||||
#define LL_SPI_CON0_SPI_MODE(n) (((n)&0x03) << 0)
|
||||
|
||||
|
||||
/***** CON1(for SPI) Register *****/
|
||||
/*! SPI DMA done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_DMA_IE_EN (1UL << 9)
|
||||
/*! SPI FIFO overflow interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_BUF_OV_IE_EN (1UL << 8)
|
||||
/*! SPI RX FIFO not empty interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_RX_BUF_NOT_EMPTY_IE_EN (1UL << 7)
|
||||
/*! SPI TX FIFO not full interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_TX_BUF_NOT_FULL_IE_EN (1UL << 6)
|
||||
/*! SPI transfers one frame interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_SSP_IE_EN (1UL << 5)
|
||||
/*! SPI DMA enable
|
||||
*/
|
||||
#define LL_SPI_CON1_DMA_EN (1UL << 4)
|
||||
/*! The SPI is set to the TX direction
|
||||
*/
|
||||
#define LL_SPI_CON1_TX_EN (1UL << 3)
|
||||
/*! SPI working mode
|
||||
*/
|
||||
#define LL_SPI_CON1_MODE(n) (((n)&0x01) << 2)
|
||||
/*! Get SPI working mode
|
||||
*/
|
||||
#define LL_SPI_CON1_GET_MODE(n) (((n)>>2) & 0x01)
|
||||
/*! SPI/IIC selection
|
||||
*/
|
||||
#define LL_SPI_CON1_SPI_I2C_SEL(n) (((n)&0x01) << 1)
|
||||
|
||||
/*! SPI/IIC module enable
|
||||
*/
|
||||
#define LL_SPI_CON1_SSP_EN (1UL << 0)
|
||||
|
||||
|
||||
/***** SSP CMD DATA(for SPI) Register *****/
|
||||
/*! Write data(32bit)
|
||||
*/
|
||||
#define LL_SPI_SSP_CMD_DATA_WRITE(n) (n)
|
||||
/*! Read data(32bit)
|
||||
*/
|
||||
#define LL_SPI_SSP_CMD_DATA_READ(n) (n)
|
||||
|
||||
|
||||
/***** BAUD(for SPI) Register *****/
|
||||
/*! Set baud rate(16bit)
|
||||
*/
|
||||
#define LL_SPI_BAUD(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx LEN(for SPI) Register *****/
|
||||
/*! Set DMA Tx length(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_TX_LEN(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx CNT(for SPI) Register *****/
|
||||
/*! The length of the byte of the transmitted data(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_TX_CNT(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx STADR(for SPI) Register *****/
|
||||
/*! DMA Tx start address(13bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_TX_STADR(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx LEN(for SPI) Register *****/
|
||||
/*! Set DMA Rx length(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_RX_LEN(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx CNT(for SPI) Register *****/
|
||||
/*! The length of the byte of the received data(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_RX_CNT(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx STADR(for SPI) Register *****/
|
||||
/*! DMA Rx start address(13bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_RX_STADR(n) (n)
|
||||
|
||||
|
||||
/***** STA(for SPI) Register *****/
|
||||
/*! SPI Slave wrong cmd pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_WRONG_CMD_PENDING (1UL << 28)
|
||||
/*! SPI Slave wiremode change pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_WIREMODE_CFG_PENDING (1UL << 23)
|
||||
/*! SPI Slave read status pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_RDSTATUS_PENDING (1UL << 22)
|
||||
/*! SPI Slave read data pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_RDDATA_PENDING (1UL << 21)
|
||||
/*! SPI Slave write data pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_WRDATA_PENDING (1UL << 20)
|
||||
/*! Clear fifo
|
||||
*/
|
||||
#define LL_SPI_STA_CLEAR_BUF_CNT (1UL << 19)
|
||||
/*! Get how many bytes of valid data in the FIFO
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_CNT(n) (((n)>>16) & 0x07)
|
||||
/*! SPI master receive data busy pending
|
||||
*/
|
||||
#define LL_SPI_STA_MASTER_RX_BUSY_PENDING (1UL << 15)
|
||||
/*! The SPI slave gets the CS pin state
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_CS_STATE (1UL << 11)
|
||||
/*! SPI module busy pending
|
||||
*/
|
||||
#define LL_SPI_STA_SSP_BUSY_PENDING (1UL << 10)
|
||||
/*! SPI slave CS(NSS) rising edge detected pending
|
||||
*/
|
||||
#define LL_SPI_STA_NSS_POS_PENDING (1UL << 5)
|
||||
/*! SPI DMA done pending
|
||||
*/
|
||||
#define LL_SPI_STA_DMA_PENDING (1UL << 4)
|
||||
/*! SPI FIFO overflow pending
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_OV_PENDING (1UL << 3)
|
||||
/*! SPI FIFO empty pending
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_EMPTY_PENDING (1UL << 2)
|
||||
/*! SPI FIFO full pending
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_FULL_PENDING (1UL << 1)
|
||||
/*! SPI transfers one frame done pending
|
||||
*/
|
||||
#define LL_SPI_STA_DONE_PENDING (1UL << 0)
|
||||
/***** SLAVESTA(for SPI) Register *****/
|
||||
#define LL_SPI_SLAVE_STA_TX_LEN(n) (((n)&0xFF) << 16)
|
||||
#define LL_SPI_SLAVE_STA_RX_LEN(n) (((n)&0xFF) << 8)
|
||||
#define LL_SPI_SLAVE_STA_RX_READY_EN (1UL << 7)
|
||||
#define LL_SPI_SLAVE_STA_TX_READY_EN (1UL << 6)
|
||||
#define LL_SPI_SLAVE_STA_SW_RESERVED (1UL << 5)
|
||||
#define LL_SPI_SLAVE_STA_WRONG_COMMAND (1UL << 4)
|
||||
#define LL_SPI_SLAVE_STA_DATA_TOGGLE (1UL << 3)
|
||||
#define LL_SPI_SLAVE_STA_TX_OVERFLOW (1UL << 2)
|
||||
#define LL_SPI_SLAVE_STA_RX_READY_FLG (1UL << 1)
|
||||
#define LL_SPI_SLAVE_STA_TX_READY_FLG (1UL << 0)
|
||||
|
||||
|
||||
/***** SSP_DLY Register *****/
|
||||
/*! Transfer delay time config
|
||||
@Note: t = APB_CLK * (n)
|
||||
*/
|
||||
#define LL_SPI_AND_IIC_SSP_DLY(n) ((n & 0xFF) << 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** @brief SPI register structure
|
||||
* @{
|
||||
*/
|
||||
struct hgspi_v1_hw {
|
||||
__IO uint32_t CON0;
|
||||
__IO uint32_t CON1;
|
||||
__IO uint32_t CMD_DATA;
|
||||
__IO uint32_t BAUD;
|
||||
__IO uint32_t TDMALEN;
|
||||
__IO uint32_t RDMALEN;
|
||||
__IO uint32_t TDMACNT;
|
||||
__IO uint32_t RDMACNT;
|
||||
__IO uint32_t TSTADR;
|
||||
__IO uint32_t RSTADR;
|
||||
__IO uint32_t STA;
|
||||
__IO uint32_t SLAVESTA;
|
||||
__IO uint32_t SSP_DLY;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGSPI_V1_HW_H_ */
|
||||
|
||||
68
sdk/driver/spi/hgspi_v2_hw.h
Normal file
68
sdk/driver/spi/hgspi_v2_hw.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef _HGGPIO_V4_HW_H_
|
||||
#define _HGGPIO_V4_HW_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***** SPICON *****/
|
||||
/*! Interrupt flag clear, write 1 to clear, write 0 to have no effect
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIINTCLR(n) (((n)&0x01) << 10)
|
||||
/*! SPI interrupt flag
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIINT(n) (((n)&0x01) << 9)
|
||||
/*! SPI status flag
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIDONE(n) (((n)&0x01) << 8)
|
||||
/*! DMA enable flag
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIDISYNCEN(n) (((n)&0x01) << 7)
|
||||
/*! Master or slave control bits
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPISM(n) (((n)&0x01) << 6)
|
||||
/*! Send or receive control bits
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIRXTX(n) (((n)&0x01) << 5)
|
||||
/*! 2-wire or 3-wire mode selection
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPI2W3W(n) (((n)&0x01) << 4)
|
||||
/*! SPI interrupt enable bit
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIINTEN(n) (((n)&0x01) << 3)
|
||||
/*! Sampling mode selection bit
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPISMPSEL(n) (((n)&0x01) << 2)
|
||||
/*! Clock line idle state selection bit
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIIDST(n) (((n)&0x01) << 1)
|
||||
/*! SPI enable bit
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_CON_SPIEN(n) (((n)&0x01) << 0)
|
||||
|
||||
|
||||
/*****SPIBAUD *****/
|
||||
/*! Baud rate setting
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_SPIBAUD(n) (((n)&0x0000FFFF) << 0)
|
||||
|
||||
|
||||
/***** SPIDATA *****/
|
||||
/*! Data register
|
||||
*/
|
||||
#define LL_SIMPLE_SPI_SPIDATA(n) (((n)&0x000000FF) << 0)
|
||||
|
||||
|
||||
struct hgspi_v2_hw {
|
||||
__IO uint32_t CON;
|
||||
__IO uint32_t BAUD;
|
||||
__IO uint32_t DATA;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGGPIO_V4_HW_H_ */
|
||||
|
||||
1558
sdk/driver/spi/hgspi_v3.c
Normal file
1558
sdk/driver/spi/hgspi_v3.c
Normal file
File diff suppressed because it is too large
Load Diff
305
sdk/driver/spi/hgspi_v3_hw.h
Normal file
305
sdk/driver/spi/hgspi_v3_hw.h
Normal file
@@ -0,0 +1,305 @@
|
||||
#ifndef _HGSPI_V3_HW_H_
|
||||
#define _HGSPI_V3_HW_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup SPI MODULE REGISTER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/***** CON0(for SPI) Register *****/
|
||||
#define LL_SPI_CON0_DUMMY_CNT(n) ((n&0x0F) << 26)
|
||||
|
||||
#define LL_SPI_CON0_SLAVE_WRONG_CMD_IE (1UL << 25)
|
||||
|
||||
#define LL_SPI_CON0_SLAVE_WIREMODE_CFG_IE (1UL << 24)
|
||||
|
||||
/*! SPI slave read status done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_RDSTATUS_IE_EN (1UL << 23)
|
||||
/*! SPI slave read data done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_RDDATA_IE_EN (1UL << 22)
|
||||
/*! SPI slave write data done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_WRDATA_IE_EN (1UL << 21)
|
||||
/*! SPI slave state enable
|
||||
*/
|
||||
#define LL_SPI_CON0_SLAVE_STATE_EN (1UL << 20)
|
||||
/*! SPI frame size
|
||||
*/
|
||||
#define LL_SPI_CON0_FRAME_SIZE(n) (((n)&0x3F) << 14)
|
||||
/*! Get SPI frame size
|
||||
*/
|
||||
#define LL_SPI_CON0_GET_FRAME_SIZE(n) (((n)>>14) & 0x3F)
|
||||
/*! SPI slave CS(NSS) rising edge interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON0_NSS_POS_IE_EN (1UL << 13)
|
||||
|
||||
#define LL_SPI_CON0_SSOE(n) ((n&0x01) << 12)
|
||||
|
||||
/*! SPI CS(NSS) output high
|
||||
* @note Only valid in SPI master mode
|
||||
*/
|
||||
#define LL_SPI_CON0_NSS_HIGH (1UL << 11)
|
||||
|
||||
/*! SPI CS(NSS) pin enable
|
||||
*/
|
||||
#define LL_SPI_CON0_NSS_PIN_EN (1UL << 10)
|
||||
|
||||
#define LL_SPI_CON0_SPI_HIGH_SPEED(n) ((n&0x3) << 8)
|
||||
|
||||
#define LL_SPI_CON0_SLAVE_DATAIN_SEL(n) ((n&0x3) << 6)
|
||||
|
||||
/*! The SPI transfers data from the low bit
|
||||
*/
|
||||
#define LL_SPI_CON0_LSB_FIRST (1UL << 5)
|
||||
/*! SPI wire mode
|
||||
*/
|
||||
#define LL_SPI_CON0_WIRE_MODE(n) (((n)&0x07) << 2)
|
||||
/*! Get SPI wire mode
|
||||
*/
|
||||
#define LL_SPI_CON0_WIRE_MODE_GET(n) (((n)>>2) & 0x03)
|
||||
/*! SPI mode
|
||||
*/
|
||||
#define LL_SPI_CON0_SPI_MODE(n) (((n)&0x03) << 0)
|
||||
|
||||
|
||||
/***** CON1(for SPI) Register *****/
|
||||
|
||||
#define LL_SPI_CON1_PING_PONG_EN(n) ((n&0x1) << 12)
|
||||
|
||||
#define LL_SPI_CON1_CLRBUFCNT_CLRSSP_EN(n) ((n&0x1) << 11)
|
||||
|
||||
#define LL_SPI_CON1_RX_TIMEOUT_IE(n) ((n&0x1) << 10)
|
||||
|
||||
/*! SPI DMA done interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_DMA_IE_EN (1UL << 9)
|
||||
/*! SPI FIFO overflow interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_BUF_OV_IE_EN (1UL << 8)
|
||||
/*! SPI RX FIFO not empty interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_RX_BUF_NOT_EMPTY_IE_EN (1UL << 7)
|
||||
/*! SPI TX FIFO not full interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_TX_BUF_NOT_FULL_IE_EN (1UL << 6)
|
||||
/*! SPI transfers one frame interrupt enable
|
||||
*/
|
||||
#define LL_SPI_CON1_SSP_IE_EN (1UL << 5)
|
||||
/*! SPI DMA enable
|
||||
*/
|
||||
#define LL_SPI_CON1_DMA_EN (1UL << 4)
|
||||
/*! The SPI is set to the TX direction
|
||||
*/
|
||||
#define LL_SPI_CON1_TX_EN (1UL << 3)
|
||||
/*! SPI working mode
|
||||
*/
|
||||
#define LL_SPI_CON1_MODE(n) (((n)&0x01) << 2)
|
||||
/*! Get SPI working mode
|
||||
*/
|
||||
#define LL_SPI_CON1_GET_MODE(n) (((n)>>2) & 0x01)
|
||||
/*! SPI/IIC selection
|
||||
*/
|
||||
#define LL_SPI_CON1_SPI_I2C_SEL(n) (((n)&0x01) << 1)
|
||||
/*! SPI/IIC module enable
|
||||
*/
|
||||
#define LL_SPI_CON1_SSP_EN (1UL << 0)
|
||||
|
||||
|
||||
/***** SSP CMD DATA(for SPI) Register *****/
|
||||
/*! Write data(32bit)
|
||||
*/
|
||||
#define LL_SPI_SSP_CMD_DATA_WRITE(n) (n)
|
||||
/*! Read data(32bit)
|
||||
*/
|
||||
#define LL_SPI_SSP_CMD_DATA_READ(n) (n)
|
||||
|
||||
|
||||
/***** TIMECON(for SPI) Register *****/
|
||||
/*! Set baud rate(16bit)
|
||||
*/
|
||||
#define LL_SPI_TIMECON_SPI_RX_DLY(n) ((n&0xFFFF)<<16)
|
||||
#define LL_SPI_TIMECON_BAUD(n) ((n&0xFFFF)<<0)
|
||||
|
||||
|
||||
/***** DMA Tx LEN(for SPI) Register *****/
|
||||
/*! Set DMA Tx length(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_TX_LEN(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx CNT(for SPI) Register *****/
|
||||
/*! The length of the byte of the transmitted data(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_TX_CNT(n) (n)
|
||||
|
||||
|
||||
/***** DMA Tx STADR(for SPI) Register *****/
|
||||
/*! DMA Tx start address(13bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_TX_STADR(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx LEN(for SPI) Register *****/
|
||||
/*! Set DMA Rx length(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_RX_LEN(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx CNT(for SPI) Register *****/
|
||||
/*! The length of the byte of the received data(12bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_RX_CNT(n) (n)
|
||||
|
||||
|
||||
/***** DMA Rx STADR(for SPI) Register *****/
|
||||
/*! DMA Rx start address(13bit)
|
||||
*/
|
||||
#define LL_SPI_DMA_RX_STADR(n) (n)
|
||||
|
||||
|
||||
/***** STA(for SPI) Register *****/
|
||||
|
||||
#define LL_SPI_STA_CLR_BUF_CNT (1UL << 31)
|
||||
|
||||
#define LL_SPI_STA_HSYNC_PEND (1UL << 21)
|
||||
|
||||
#define LL_SPI_STA_VSYNC_PEND (1UL << 20)
|
||||
|
||||
#define LL_SPI_STA_DMA_PPBUF_SEL (1UL << 19)
|
||||
|
||||
#define LL_SPI_STA_RX_TIMEOUT_PEND (1UL << 18)
|
||||
|
||||
#define LL_SPI_STA_MODF (1UL << 17)
|
||||
|
||||
/*! SPI Slave wrong cmd pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_WRONG_CMD_PENDING (1UL << 16)
|
||||
/*! SPI Slave wiremode change pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_WIREMODE_CFG_PENDING (1UL << 15)
|
||||
/*! SPI Slave read status pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_RDSTATUS_PENDING (1UL << 14)
|
||||
/*! SPI Slave read data pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_RDDATA_PENDING (1UL << 13)
|
||||
/*! SPI Slave write data pending
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_WRDATA_PENDING (1UL << 12)
|
||||
/*! Clear fifo
|
||||
*/
|
||||
#define LL_SPI_STA_CLEAR_BUF_CNT (1UL << 9)
|
||||
/*! Get how many bytes of valid data in the FIFO
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_CNT(n) (((n)>>9) & 0x07)
|
||||
/*! SPI master receive data busy pending
|
||||
*/
|
||||
#define LL_SPI_STA_MASTER_RX_BUSY_PENDING (1UL << 8)
|
||||
/*! The SPI slave gets the CS pin state
|
||||
*/
|
||||
#define LL_SPI_STA_SLAVE_CS_STATE (1UL << 7)
|
||||
/*! SPI module busy pending
|
||||
*/
|
||||
#define LL_SPI_STA_SSP_BUSY_PENDING (1UL << 6)
|
||||
/*! SPI slave CS(NSS) rising edge detected pending
|
||||
*/
|
||||
#define LL_SPI_STA_NSS_POS_PENDING (1UL << 5)
|
||||
/*! SPI DMA done pending
|
||||
*/
|
||||
#define LL_SPI_STA_DMA_PENDING (1UL << 4)
|
||||
/*! SPI FIFO overflow pending
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_OV_PENDING (1UL << 3)
|
||||
/*! SPI FIFO empty pending
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_EMPTY_PENDING (1UL << 2)
|
||||
/*! SPI FIFO full pending
|
||||
*/
|
||||
#define LL_SPI_STA_BUF_FULL_PENDING (1UL << 1)
|
||||
/*! SPI transfers one frame done pending
|
||||
*/
|
||||
#define LL_SPI_STA_DONE_PENDING (1UL << 0)
|
||||
|
||||
|
||||
/***** RBUF(for SPI) Register *****/
|
||||
#define LL_SPI_RBUF(n) ((n) & 0xFF)
|
||||
|
||||
|
||||
/***** RX_TIMEOUTCON(for SPI) Register *****/
|
||||
#define LL_SPI_RX_TIMEOUTCON(n) ((n&0x1FFFFFFF)<<1)
|
||||
|
||||
#define LL_SPI_RX_TIMEOUT_EN(n) ((n&0x1)<<0)
|
||||
|
||||
|
||||
/***** RSTADR1(for SPI) Register *****/
|
||||
#define LL_SPI_RSTADR1(n) (n)
|
||||
|
||||
|
||||
/***** VSYNV_TCON(for SPI) Register *****/
|
||||
#define LL_SPI_VSYNV_TCON_VSYNC_TIME(n) ((n&0x1FFFFF)<<8)
|
||||
|
||||
#define LL_SPI_VSYNV_TCON_VSYNC_MASK_CNT(n) ((n&0x3F)<<1)
|
||||
|
||||
#define LL_SPI_VSYNV_TCON_VHSYNC_DETEN(n) ((n&0x01)<<0)
|
||||
|
||||
|
||||
/***** HSYNV_TCON(for SPI) Register *****/
|
||||
#define LL_SPI_HSYNV_TCON_HSYNC_TIME(n) ((n&0xFFFF)<<8)
|
||||
|
||||
#define LL_SPI_HSYNV_TCON_HSYNC_MASK_CNT(n) ((n&0x3F)<<0)
|
||||
|
||||
|
||||
/***** SLAVESTA(for SPI) Register *****/
|
||||
#define LL_SPI_SLAVE_STA_TX_LEN(n) (((n)&0xFF) << 16)
|
||||
#define LL_SPI_SLAVE_STA_RX_LEN(n) (((n)&0xFF) << 8)
|
||||
#define LL_SPI_SLAVE_STA_RX_READY_EN (1UL << 7)
|
||||
#define LL_SPI_SLAVE_STA_TX_READY_EN (1UL << 6)
|
||||
#define LL_SPI_SLAVE_STA_SW_RESERVED (1UL << 5)
|
||||
#define LL_SPI_SLAVE_STA_WRONG_COMMAND (1UL << 4)
|
||||
#define LL_SPI_SLAVE_STA_DATA_TOGGLE (1UL << 3)
|
||||
#define LL_SPI_SLAVE_STA_TX_OVERFLOW (1UL << 2)
|
||||
#define LL_SPI_SLAVE_STA_RX_READY_FLG (1UL << 1)
|
||||
#define LL_SPI_SLAVE_STA_TX_READY_FLG (1UL << 0)
|
||||
|
||||
|
||||
|
||||
/** @brief SPI register structure
|
||||
* @{
|
||||
*/
|
||||
struct hgspi_v3_hw {
|
||||
__IO uint32_t CON0;
|
||||
__IO uint32_t CON1;
|
||||
__IO uint32_t CMD_DATA;
|
||||
__IO uint32_t TIMECON;
|
||||
__IO uint32_t TDMALEN;
|
||||
__IO uint32_t RDMALEN;
|
||||
__IO uint32_t TDMACNT;
|
||||
__IO uint32_t RDMACNT;
|
||||
__IO uint32_t TSTADR;
|
||||
__IO uint32_t RSTADR;
|
||||
__IO uint32_t STA1;
|
||||
__IO uint32_t STA2;
|
||||
__IO uint32_t SLAVESTA;
|
||||
__IO uint32_t OWNADRCON;
|
||||
__IO uint32_t RBUF;
|
||||
__IO uint32_t TIMEOUTCON;
|
||||
__IO uint32_t RXTIMEOUTCON;
|
||||
__IO uint32_t RSTADR1;
|
||||
__IO uint32_t VSYNC_TCON;
|
||||
__IO uint32_t HSYNC_TCON;
|
||||
__IO uint32_t LINE_LEN;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGSPI_V3_HW_H_ */
|
||||
|
||||
288
sdk/driver/sysaes/hg_sysaes_v3.c
Normal file
288
sdk/driver/sysaes/hg_sysaes_v3.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hg_sysaes_v3.c
|
||||
* @author HUGE-IC Application Team
|
||||
* @version TXW81X
|
||||
* @date
|
||||
* @brief standard aes support aes 128/192/256
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2019 HUGE-IC</center></h2>
|
||||
*
|
||||
*
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#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/sysaes/hg_sysaes_v3.h"
|
||||
#include "hg_sysaes_v3_hw.h"
|
||||
#include "hal/sysaes.h"
|
||||
|
||||
#define SYS_AES_DEBUG_ERR_ENABLE 1
|
||||
|
||||
|
||||
#if SYS_AES_DEBUG_ERR_ENABLE
|
||||
#define SYS_AES_ERR_PRINTF(fmt, args...) os_printf(fmt, ##args)
|
||||
#else
|
||||
#define SYS_AES_ERR_PRINTF(fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void hg_sysaes_v3_irq_handler(void *data)
|
||||
{
|
||||
struct hg_sysaes_v3 *sysaes = (struct hg_sysaes_v3 *)data;
|
||||
struct hg_sysaes_v3_hw *hw = (struct hg_sysaes_v3_hw *)sysaes->hw;
|
||||
hw->AES_STAT = AES_STAT_COMP_PD_MSK;
|
||||
os_sema_up(&sysaes->done);
|
||||
}
|
||||
|
||||
static void hg_sysaes_v3_fill_key(struct sysaes_dev *dev, struct sysaes_para *para)
|
||||
{
|
||||
struct hg_sysaes_v3 *sysaes = (struct hg_sysaes_v3 *)dev;
|
||||
struct hg_sysaes_v3_hw *hw = (struct hg_sysaes_v3_hw *)sysaes->hw;
|
||||
for (uint8 i = 0; i < 8; ++i) {
|
||||
hw->KEY[i] = get_unaligned_le32((const void*)¶->key[i*4]);
|
||||
}
|
||||
}
|
||||
|
||||
static int32 hg_sysaes_v3_hdl(struct sysaes_dev *dev, struct sysaes_para *para, uint32 flags)
|
||||
{
|
||||
int32 ret;
|
||||
uint32 aes_key_len = 0;
|
||||
uint32 aes_mode = 0;
|
||||
struct hg_sysaes_v3 *sysaes = (struct hg_sysaes_v3 *)dev;
|
||||
struct hg_sysaes_v3_hw *hw = (struct hg_sysaes_v3_hw *)sysaes->hw;
|
||||
|
||||
if ((para->key_len > AES_KEY_LEN_BIT_256)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
ret = os_mutex_lock(&sysaes->lock, osWaitForever);
|
||||
if (ret) {
|
||||
if (flags == ENCRYPT) {
|
||||
SYS_AES_ERR_PRINTF("sysaes encrypt lock timeout!\r\n");
|
||||
} else {
|
||||
SYS_AES_ERR_PRINTF("sysaes decrypt lock timeout!\r\n");
|
||||
}
|
||||
os_mutex_unlock(&sysaes->lock);
|
||||
return RET_ERR;
|
||||
}
|
||||
os_sema_eat(&sysaes->done);
|
||||
if (flags == ENCRYPT) {
|
||||
hw->AES_CTRL &= ~AES_CTRL_EOD_MSK;
|
||||
} else {
|
||||
hw->AES_CTRL |= AES_CTRL_EOD_MSK;
|
||||
}
|
||||
switch (para->mode) {
|
||||
case AES_MODE_ECB:
|
||||
aes_mode = AES_CTRL_AES_ECB;
|
||||
break;
|
||||
case AES_MODE_CBC:
|
||||
aes_mode = AES_CTRL_AES_CBC;
|
||||
break;
|
||||
case AES_MODE_CTR:
|
||||
aes_mode = AES_CTRL_AES_CTR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hw->AES_CTRL = (hw->AES_CTRL & ~ AES_CTRL_AES_MODE_MSK) | (aes_mode & AES_CTRL_AES_MODE_MSK);
|
||||
switch (para->key_len) {
|
||||
case AES_KEY_LEN_BIT_128:
|
||||
aes_key_len = AES_CTRL_AES_128;
|
||||
break;
|
||||
case AES_KEY_LEN_BIT_192:
|
||||
aes_key_len = AES_CTRL_AES_192;
|
||||
break;
|
||||
case AES_KEY_LEN_BIT_256:
|
||||
aes_key_len = AES_CTRL_AES_256;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hw->AES_CTRL = (hw->AES_CTRL & ~ AES_CTRL_AES_KEYLEN_MSK) |
|
||||
(aes_key_len & AES_CTRL_AES_KEYLEN_MSK) |
|
||||
AES_CTRL_IRQ_EN_MSK;
|
||||
|
||||
// READ_ADDR
|
||||
sys_dcache_clean_range_unaligned((uint32 *)para->src, para->aes_len);
|
||||
// WRITE_ADDR
|
||||
sys_dcache_invalid_range_unaligned((uint32 *)para->dest, para->aes_len);
|
||||
|
||||
hw->SADDR = (uint32)para->src;
|
||||
hw->DADDR = (uint32)para->dest;
|
||||
hw->BLOCK_NUM = para->aes_len;
|
||||
hw->AES_CTRL &= ~AES_CTRL_MOD_MSK;
|
||||
for (uint8 i = 0; i < 8; ++i) {
|
||||
hw->KEY[i] = get_unaligned_le32((const void*)¶->key[i*4]);
|
||||
}
|
||||
for (uint8 i = 0; i < 4; ++i) {
|
||||
hw->IV[i] = get_unaligned_le32((const void*)¶->iv[i*4]);
|
||||
}
|
||||
if(para->mode == AES_MODE_CTR) {
|
||||
hw->IV[3] = (para->iv[12]) | (para->iv[13] << 8) | (para->iv[15] << 16) | (para->iv[14] << 24);
|
||||
}
|
||||
|
||||
hw->AES_STAT = AES_STAT_COMP_PD_MSK;
|
||||
while(ll_sysctrl_dma2ahb_is_busy(DMA2AHB_BURST_CH_SYSAES_WR));
|
||||
hw->AES_CTRL |= AES_CTRL_START_MSK;
|
||||
ret = os_sema_down(&sysaes->done, 2000);
|
||||
if (!ret) {
|
||||
sysctrl_sysaes_reset();
|
||||
if (flags == ENCRYPT) {
|
||||
SYS_AES_ERR_PRINTF("sysaes encrypt wait irq timeout!\r\n");
|
||||
} else {
|
||||
SYS_AES_ERR_PRINTF("sysaes decrypt wait irq timeout!\r\n");
|
||||
}
|
||||
os_mutex_unlock(&sysaes->lock);
|
||||
return RET_ERR;
|
||||
}
|
||||
os_mutex_unlock(&sysaes->lock);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hg_sysaes_v3_encrypt(struct sysaes_dev *dev, struct sysaes_para *para)
|
||||
{
|
||||
if (para->mode > AES_MODE_CTR) {
|
||||
return RET_ERR;
|
||||
}
|
||||
//hg_sysaes_v3_fill_key(dev, para);
|
||||
return hg_sysaes_v3_hdl(dev, para, ENCRYPT);
|
||||
}
|
||||
|
||||
static int32 hg_sysaes_v3_decrypt(struct sysaes_dev *dev, struct sysaes_para *para)
|
||||
{
|
||||
if (para->mode > AES_MODE_CTR) {
|
||||
return RET_ERR;
|
||||
}
|
||||
//hg_sysaes_v3_fill_key(dev, para);
|
||||
if (para->mode == AES_MODE_CTR) {
|
||||
return hg_sysaes_v3_hdl(dev, para, ENCRYPT);
|
||||
} else {
|
||||
return hg_sysaes_v3_hdl(dev, para, DECRYPT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_SLEEP
|
||||
// #define HGAES_SLEEP_TEST(PARA) hg_sysaes_test_printf(PARA)
|
||||
#define HGAES_SLEEP_TEST(PARA)
|
||||
|
||||
void hg_sysaes_test_printf(struct sysaes_dev *dev)
|
||||
{
|
||||
uint32_t iv[4] = {0};
|
||||
volatile uint32_t pt[8];
|
||||
volatile uint32_t ct[8];
|
||||
uint32_t ptsum = 0;
|
||||
uint32_t ctsum = 0;
|
||||
uint32_t decsum = 0;
|
||||
for (int i = 0;i<8;i++)
|
||||
{
|
||||
pt[i] = 0x12345678+i;
|
||||
ptsum += pt[i];
|
||||
}
|
||||
|
||||
struct sysaes_para para = {
|
||||
.mode = AES_MODE_ECB,
|
||||
.key_len = AES_KEY_LEN_BIT_256,
|
||||
.dest = (void*)ct,
|
||||
.src = (void*)pt,
|
||||
.iv = (void*)iv,
|
||||
.aes_len = 32,
|
||||
};
|
||||
memset(para.key, 0, 32);
|
||||
hg_sysaes_v3_encrypt(dev, ¶);
|
||||
for (int i = 0;i<8;i++)
|
||||
{
|
||||
ctsum += ct[i];
|
||||
}
|
||||
_os_printf("ptsum: %x\r\n", ptsum);
|
||||
_os_printf("ctsum: %x\r\n", ctsum);
|
||||
|
||||
para.dest = (void*)pt;
|
||||
para.src = (void*)ct;
|
||||
hg_sysaes_v3_decrypt(dev, ¶);
|
||||
for (int i = 0;i<8;i++)
|
||||
{
|
||||
decsum += pt[i];
|
||||
}
|
||||
_os_printf("decsum: %x\r\n", decsum);
|
||||
if ((ptsum != decsum) || (ptsum != 0x91a2b3dc) || (ctsum != 0x2e3c234f)) {
|
||||
_os_printf("sysaes lp err\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32 hg_sysaes_v3_suspend(struct dev_obj *dev)
|
||||
{
|
||||
int32 ret = 0;
|
||||
struct hg_sysaes_v3 *sysaes = (struct hg_sysaes_v3 *)dev;
|
||||
struct hg_sysaes_v3_hw *hw = (struct hg_sysaes_v3_hw *)sysaes->hw;
|
||||
(void)hw;
|
||||
if (sysaes->flags & BIT(HG_SYSAES_FLAGS_SUSPEND)) {
|
||||
return RET_OK;
|
||||
}
|
||||
HGAES_SLEEP_TEST(dev);
|
||||
ret = os_mutex_lock(&sysaes->lock, osWaitForever);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
irq_disable(sysaes->irq_num);
|
||||
|
||||
sysctrl_sysaes_clk_close();
|
||||
sysaes->flags |= BIT(HG_SYSAES_FLAGS_SUSPEND);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hg_sysaes_v3_resume(struct dev_obj *dev)
|
||||
{
|
||||
int32 ret = 0;
|
||||
struct hg_sysaes_v3 *sysaes = (struct hg_sysaes_v3 *)dev;
|
||||
struct hg_sysaes_v3_hw *hw = (struct hg_sysaes_v3_hw *)sysaes->hw;
|
||||
(void)hw;
|
||||
if (sysaes->flags & BIT(HG_SYSAES_FLAGS_SUSPEND)) {
|
||||
ret = os_mutex_unlock(&sysaes->lock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
sysctrl_sysaes_clk_open();
|
||||
sysctrl_sysaes_reset();
|
||||
sysaes->flags &= ~ BIT(HG_SYSAES_FLAGS_SUSPEND);
|
||||
irq_enable(sysaes->irq_num);
|
||||
HGAES_SLEEP_TEST(dev);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct aes_hal_ops aes_v3_ops = {
|
||||
.encrypt = hg_sysaes_v3_encrypt,
|
||||
.decrypt = hg_sysaes_v3_decrypt,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hg_sysaes_v3_suspend,
|
||||
.ops.resume = hg_sysaes_v3_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
__init int32 hg_sysaes_v3_attach(uint32 dev_id, struct hg_sysaes_v3 *sysaes)
|
||||
{
|
||||
sysaes->dev.dev.ops = (const struct devobj_ops *)&aes_v3_ops;
|
||||
os_mutex_init(&sysaes->lock);
|
||||
os_sema_init(&sysaes->done, 0);
|
||||
sysctrl_sysaes_clk_open();
|
||||
sysctrl_sysaes_reset();
|
||||
request_irq(sysaes->irq_num, hg_sysaes_v3_irq_handler, sysaes);
|
||||
irq_enable(sysaes->irq_num);
|
||||
dev_register(dev_id, (struct dev_obj *)sysaes);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
54
sdk/driver/sysaes/hg_sysaes_v3_hw.h
Normal file
54
sdk/driver/sysaes/hg_sysaes_v3_hw.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef _HG_SYSAES_V3_HW_H_
|
||||
#define _HG_SYSAES_V3_HW_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BLOCK_NUM_NUM_MSK 0x000fffff
|
||||
#define BLOCK_NUM_NUM_SHIFT 0
|
||||
|
||||
#define AES_CTRL_START_MSK 0x00000001
|
||||
#define AES_CTRL_START_SHIFT 0
|
||||
#define AES_CTRL_EOD_MSK 0x00000002
|
||||
#define AES_CTRL_EOD_SHIFT 1
|
||||
#define AES_CTRL_MOD_MSK 0x00000004
|
||||
#define AES_CTRL_MOD_SHIFT 2
|
||||
#define AES_CTRL_IRQ_EN_MSK 0x00000008
|
||||
#define AES_CTRL_IRQ_EN_SHIFT 3
|
||||
|
||||
#define AES_CTRL_AES_128 0
|
||||
#define AES_CTRL_AES_192 BIT(4)
|
||||
#define AES_CTRL_AES_256 BIT(5)
|
||||
#define AES_CTRL_AES_KEYLEN_MSK (BIT(4)|BIT(5))
|
||||
#define AES_CTRL_AES_ECB 0
|
||||
#define AES_CTRL_AES_CBC BIT(6)
|
||||
#define AES_CTRL_AES_CTR BIT(7)
|
||||
#define AES_CTRL_AES_MODE_MSK (BIT(6)|BIT(7))
|
||||
|
||||
#define AES_STAT_COMP_PD_MSK 0x00000001
|
||||
#define AES_STAT_COMP_PD_SHIFT 0
|
||||
|
||||
enum hg_sysaes_v3_mode {
|
||||
ENCRYPT,
|
||||
DECRYPT,
|
||||
};
|
||||
|
||||
enum hg_sysaes_v3_flags {
|
||||
HG_SYSAES_FLAGS_SUSPEND,
|
||||
};
|
||||
|
||||
struct hg_sysaes_v3_hw {
|
||||
__IO uint32 KEY[8];
|
||||
__IO uint32 SADDR;
|
||||
__IO uint32 DADDR;
|
||||
__IO uint32 BLOCK_NUM;
|
||||
uint32 RESERVED0[1];
|
||||
__IO uint32 IV[4];
|
||||
__IO uint32 AES_CTRL;
|
||||
__IO uint32 AES_STAT;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _HG_SYSAES_V3_H_ */
|
||||
1192
sdk/driver/timer/hgtimer_v4.c
Normal file
1192
sdk/driver/timer/hgtimer_v4.c
Normal file
File diff suppressed because it is too large
Load Diff
311
sdk/driver/timer/hgtimer_v4_hw.h
Normal file
311
sdk/driver/timer/hgtimer_v4_hw.h
Normal file
@@ -0,0 +1,311 @@
|
||||
#ifndef _HGTIMER_V4_HW_H
|
||||
#define _HGTIMER_V4_HW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***** TIMERx CON Register *****/
|
||||
/*! Timer IR selection whether lsb first send (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_CON_IR_TMR_FST_LSB_SEL (1UL << 29)
|
||||
/*! Timer IR function logic 0 PWM polarity selection (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_CON_IR_ZERO_PWMPOL (1UL << 28)
|
||||
/*! Timer IR function logic 1 PWM polarity selection (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_CON_IR_ONE_PWMPOL (1UL << 27)
|
||||
/*! Timer IR function enable (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_CON_IR_EN (1UL << 26)
|
||||
/*! PWM polarity selection in TIMER module
|
||||
*/
|
||||
#define LL_TIMER_CON_PWMPOL (1UL << 25)
|
||||
/*! The polarity of capture event 1 is selected: 0 = rising edge, 1 = falling edge.
|
||||
*/
|
||||
#define LL_TIMER_CON_CAP1POL(n) ((n & 0x1) << 21)
|
||||
/*! When the capture event 1 occurs, the value of the CNT is automatically cleared.
|
||||
*/
|
||||
#define LL_TIMER_CON_CTRRST1 (1UL << 17)
|
||||
/*! The number of the Capture register:
|
||||
* 00 : Capture data store in CAP1
|
||||
* 01 : Capture data store in CAP1 CAP2
|
||||
* 10 : Capture data store in CAP1 CAP2 CAP3
|
||||
* 11 : Capture data store in CAP1 CAP2 CAP3 CAP4
|
||||
*/
|
||||
#define LL_TIMER_CON_CAP_CNT(n) (((n)&0x3) << 15)
|
||||
/*! Capture selection:
|
||||
* 00 : GPIO
|
||||
* 01 : GPIO OR
|
||||
* 10 : compare0 output
|
||||
* 11 : compare1 output
|
||||
*/
|
||||
#define LL_TIMER_CON_CAP_SEL(n) (((n)&0x3) << 13)
|
||||
/*! Output sync signal selection:
|
||||
* 00 : CNT value = PRD value
|
||||
* 01 : CNT value = CMP value
|
||||
* 10 : Output SYNCI value to SYNCO
|
||||
* 11 : PWM output is assigned to SYNCO
|
||||
*/
|
||||
#define LL_TIMER_CON_SYNCO_SEL(n) (((n)&0x3) << 11)
|
||||
/*! Synci polarity inversion:
|
||||
* 1 : Invert
|
||||
* 0 : not reversed
|
||||
*/
|
||||
#define LL_TIMER_CON_SYNCI_POL (1UL << 10)
|
||||
/*! Synci function selection
|
||||
* 00 : disable
|
||||
* 01 : kick start
|
||||
* 10 : reset
|
||||
* 11 : gating
|
||||
*/
|
||||
#define LL_TIMER_CON_SLAVE_MODE(n) (((n)&0x3) << 8)
|
||||
/*! Timer prescaler settings:
|
||||
* 000 : 0 frequency division
|
||||
* 001 : 2 frequency division
|
||||
* 010 : 4 frequency division
|
||||
* 011 : 8 frequency division
|
||||
* 100 : 16 frequency division
|
||||
* 101 : 32 frequency division
|
||||
* 110 : 64 frequency division
|
||||
* 111 : 128 frequency division
|
||||
*/
|
||||
#define LL_TIMER_CON_PSC(n) (((n)&0x7) << 5)
|
||||
/*! Timer counter source select bits:
|
||||
* 001 : Internal high speed RC
|
||||
* 010 : Internal low speed RC
|
||||
* 011 : External crystal oscillator divided by 2 clocks
|
||||
* 100 : timer inc pin rising
|
||||
* 101 : timer inc pin falling
|
||||
* 110 : timer inc pin rising and falling
|
||||
* Others : system clock
|
||||
*/
|
||||
#define LL_TIMER_CON_INC_SRC_SEL(n) (((n)&0x7) << 2)
|
||||
/*! Timer mode select bits:
|
||||
* 00 : timer counter mode
|
||||
* 01 : timer pwm mode
|
||||
* 10 : timer capture mode
|
||||
* Others : reservation
|
||||
*/
|
||||
#define LL_TIMER_CON_MODE_SEL(n) (((n)&0x3) << 0)
|
||||
|
||||
|
||||
/***** TIMERx EN Register *****/
|
||||
/*! TMR enable signal, active high.
|
||||
*/
|
||||
#define LL_TIMER_EN_TMREN (1UL << 0)
|
||||
|
||||
|
||||
/***** TIMERx IE Register *****/
|
||||
/*! Timer IR TX word done interrupt enable (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_IE_IR_TX_WORD_DONE_IE (1UL << 11)
|
||||
/*! Timer IR TX done interrupt enable (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_IE_IR_TX_DONE_IE (1UL << 10)
|
||||
/*! Dma buffer full interrupt enable.
|
||||
*/
|
||||
#define LL_TIMER_IE_DMA_FL_IE (1UL << 9)
|
||||
/*! Dma buffer half full interrupt enable.
|
||||
*/
|
||||
#define LL_TIMER_IE_DMA_HF_IE (1UL << 8)
|
||||
/*! The slave mode trigger mode or reset mode interrupt enable.
|
||||
*/
|
||||
#define LL_TIMER_IE_SLAVE_IE (1UL << 7)
|
||||
/*! When the CNT value is equal to the CMP value, the interrupt is enabled and is valid only in pwm mode.
|
||||
*/
|
||||
#define LL_TIMER_IE_CMP_IE (1UL << 6)
|
||||
/*! When the CNT value is equal to the PRD value, the interrupt is enabled and is valid only in the counter mode/PWM mode.
|
||||
*/
|
||||
#define LL_TIMER_IE_PRD_IE (1UL << 5)
|
||||
/*! When the CNT value overflows (16'hffff), the interrupt is enabled.
|
||||
*/
|
||||
#define LL_TIMER_IE_OVF_IE (1UL << 4)
|
||||
/*! When the capture event 1 occurs, the interrupt is enabled.
|
||||
@note: none this capture event interrupt
|
||||
*/
|
||||
#define LL_TIMER_IE_CAP1_IE (1UL << 0)
|
||||
|
||||
|
||||
/***** TIMERx CNT Register *****/
|
||||
/*! Count register.
|
||||
*/
|
||||
#define LL_TIMER_CNT(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMERx FLG Register *****/
|
||||
/*! Timer IR TX word done interrupt flag (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_IE_IR_TX_WORD_DONE_FLG (1UL << 11)
|
||||
/*! Timer IR TX done interrupt flag (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_IE_IR_TX_DONE_FLG (1UL << 10)
|
||||
/*! Dma buffer full sign.
|
||||
*/
|
||||
#define LL_TIMER_IE_DMA_FL_FLG (1UL << 9)
|
||||
/*! Dma buffer half full sign.
|
||||
*/
|
||||
#define LL_TIMER_IE_DMA_HF_FLG (1UL << 8)
|
||||
/*! The slave mode flag (reset or trigger only).
|
||||
*/
|
||||
#define LL_TIMER_IE_SLAVE_FLG (1UL << 7)
|
||||
/*! The CNT value is equal to the CMP value flag and is valid only in pwm mode.
|
||||
*/
|
||||
#define LL_TIMER_IE_CMP_FLG (1UL << 6)
|
||||
/*! The CNT value is equal to the PRD value flag and is valid only in counter mode/PWM mode.
|
||||
*/
|
||||
#define LL_TIMER_IE_PRD_FLG (1UL << 5)
|
||||
/*! CNT value overflow (16'hffff) flag.
|
||||
*/
|
||||
#define LL_TIMER_IE_OVF_FLG (1UL << 4)
|
||||
/*! Capture event 1 occurs.
|
||||
*/
|
||||
#define LL_TIMER_IE_CAP1_FLG (1UL << 0)
|
||||
|
||||
|
||||
/***** TIMERx CLR Register *****/
|
||||
/*! Timer IR TX word done interrupt clear (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_IE_IR_TX_WORD_DONE_CLR (1UL << 11)
|
||||
/*! Timer IR TX done interrupt clear (for TIMER1/2 only)
|
||||
*/
|
||||
#define LL_TIMER_IE_IR_TX_DONE_CLR (1UL << 10)
|
||||
/*! Dma buffer full sign clear.
|
||||
*/
|
||||
#define LL_TIMER_IE_DMA_FL_CLR (1UL << 9)
|
||||
/*! Dma buffer half full sign clear.
|
||||
*/
|
||||
#define LL_TIMER_IE_DMA_HF_CLR (1UL << 8)
|
||||
/*! The slave mode flag (reset or trigger only) clear.
|
||||
*/
|
||||
#define LL_TIMER_IE_SLAVE_CLR (1UL << 7)
|
||||
/*! The CNT value is equal to the CMP value flag clear.
|
||||
*/
|
||||
#define LL_TIMER_IE_CMP_CLR (1UL << 6)
|
||||
/*! The CNT value is equal to the PRD value flag clear.
|
||||
*/
|
||||
#define LL_TIMER_IE_PRD_CLR (1UL << 5)
|
||||
/*! The CNT value overflow (16'hffff) flag is cleared.
|
||||
*/
|
||||
#define LL_TIMER_IE_OVF_CLR (1UL << 4)
|
||||
/*! Capture event 1 occurs flag clear.
|
||||
*/
|
||||
#define LL_TIMER_IE_CAP1_CLR (1UL << 0)
|
||||
|
||||
|
||||
/***** TIMERx CAP1/PR Register *****/
|
||||
/*! Capture mode : capture register 1
|
||||
* Timing mode/PWM mode: Count period register
|
||||
*/
|
||||
#define LL_TIMER_CMP1_PR(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMERx CAP2/CMP Register *****/
|
||||
/*! Capture mode : capture register 2
|
||||
* Timing mode/PWM mode: compare register
|
||||
*/
|
||||
#define LL_TIMER_CMP2_CMP(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMERx CAP3/PR_SD Register *****/
|
||||
/*! Capture mode : capture register 3
|
||||
* Timing mode/PWM mode: counting period shadow register
|
||||
*/
|
||||
#define LL_TIMER_CMP3_PR_SD(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMERx CAP4/CMP_SD Register *****/
|
||||
/*! Capture mode : capture register 4
|
||||
* Timing mode/PWM mode: Compare shadow registers
|
||||
*/
|
||||
#define LL_TIMER_CMP4_CMP_SD(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
/***** TIMERx DCCTL Register *****/
|
||||
/*! Dma mode selection
|
||||
* 0 : Single mode, after the specified dma length is completed, disable TMR.
|
||||
* 1 : Loop mode, after the dma length is specified, restart from the start address.
|
||||
*/
|
||||
#define LL_TIMER_DMA_LPBK (1UL << 1)
|
||||
/*! Dma enabled.
|
||||
*/
|
||||
#define LL_TIMER_DMA_EN (1UL << 0)
|
||||
|
||||
|
||||
/***** TIMERx DADR Register *****/
|
||||
/*! Dma starting address.
|
||||
*/
|
||||
#define LL_TIMER_DADR_STADR(n) (((n)&0xFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMERx DLEN Register *****/
|
||||
/*! Dma buffer length (32bit), if the buffer is n, the configuration is n-1;
|
||||
*/
|
||||
#define LL_TIMER_DLEN_LEN(n) (((n)&0xFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMERx DCNT Register *****/
|
||||
/*! The number of dma data is valid.
|
||||
*/
|
||||
#define LL_TIMER_DCNT_CNT(n) (((n)&0xFFFF) << 0)
|
||||
|
||||
|
||||
/***** TIMER ALLCON Register *****/
|
||||
/*! The timer3 sync count value is cleared.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR3_SYNC (1UL << 11)
|
||||
/*! The timer2 sync count value is cleared.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR2_SYNC (1UL << 10)
|
||||
/*! The timer1 sync count value is cleared.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR1_SYNC (1UL << 9)
|
||||
/*! The timer0 sync count value is cleared.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR0_SYNC (1UL << 8)
|
||||
/*! Timer3 starts counting.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR3_KICK (1UL << 3)
|
||||
/*! Timer2 starts counting.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR2_KICK (1UL << 2)
|
||||
/*! Timer1 starts counting.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR1_KICK (1UL << 1)
|
||||
/*! Timer0 starts counting.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_TMR0_KICK (1UL << 0)
|
||||
/*! Configure the trigger path for the sync count of TIMER.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_SYNC_COUNT_ALL(n) (((n)&0x3F) << 8)
|
||||
/*! Configure the synchronous trigger path of TIMER.
|
||||
*/
|
||||
#define LL_TIMER_ALLCON_KICK_ALL(n) (((n)&0x3F) << 0)
|
||||
|
||||
|
||||
|
||||
struct hgtimer_v4_hw {
|
||||
__IO uint32_t TMR_CON;
|
||||
__IO uint32_t TMR_EN;
|
||||
__IO uint32_t TMR_IE;
|
||||
__IO uint32_t TMR_CNT;
|
||||
__IO uint32_t TMR_FLG;
|
||||
__IO uint32_t TMR_CLR;
|
||||
__IO uint32_t TMR_CAP1;
|
||||
__IO uint32_t TMR_CAP2;
|
||||
__IO uint32_t TMR_CAP3;
|
||||
__IO uint32_t TMR_CAP4;
|
||||
/* The following registers only for timer1 & timer2 */
|
||||
__IO uint32_t TMR_DCTL;
|
||||
__IO uint32_t TMR_DADR;
|
||||
__IO uint32_t TMR_DLEN;
|
||||
__IO uint32_t TMR_DCNT;
|
||||
__IO uint32_t TMR_IR_BCNT;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGTIMER_V4_HW_H */
|
||||
|
||||
1096
sdk/driver/timer/hgtimer_v7.c
Normal file
1096
sdk/driver/timer/hgtimer_v7.c
Normal file
File diff suppressed because it is too large
Load Diff
96
sdk/driver/timer/hgtimer_v7_hw.h
Normal file
96
sdk/driver/timer/hgtimer_v7_hw.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef _HGTIMER_V7_HW_H
|
||||
#define _HGTIMER_V7_HW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***** SINPLE TIMERx CTL Register *****/
|
||||
/*! Capture selection:
|
||||
* 00 : GPIO
|
||||
* 01 : GPIO OR
|
||||
* 10 : compare0 output
|
||||
* 11 : compare1 output
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_CAP_SEL(n) (((n)&0x3) << 16)
|
||||
/*!Period break flag
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_PERIOD_ING (1UL << 15)
|
||||
/*!Mark of capture
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_CAP_ING (1UL << 14)
|
||||
/*!Periodic interrupt was enabled
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_PERIOD_IE (1UL << 13)
|
||||
/*!Capture interrupt enable
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_CAP_IE (1UL << 12)
|
||||
/*! Timer prescaler settings:
|
||||
* 000 : 0 frequency division
|
||||
* 001 : 2 frequency division
|
||||
* 010 : 4 frequency division
|
||||
* 011 : 8 frequency division
|
||||
* 100 : 16 frequency division
|
||||
* 101 : 32 frequency division
|
||||
* 110 : 64 frequency division
|
||||
* 111 : 128 frequency division
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_PSC(n) (((n)&0x7) << 8)
|
||||
/*! Capture source edge selection
|
||||
* 0x0: Capture occurs during rising edge
|
||||
* 0x1: Capture occurs at falling edge
|
||||
* 0x2: Capture occurs along both the rising and falling edges
|
||||
* 0x3: Capture occurs along both the rising and falling edges
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_EDG_SCL(n) (((n)&0x3) << 6)
|
||||
|
||||
/*! simple timer mode select bits:
|
||||
* 01 : timer counter mode
|
||||
* 10 : timer pwm mode
|
||||
* 11 : timer capture mode
|
||||
* This bit of non-zero time counting is enabled
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_MODE_SEL(n) (((n)&0x3) << 4)
|
||||
|
||||
/*! Timer counter source select bits:
|
||||
8 000 : Select GPIO (CAP PIN) as the clock source Select the rising edge as the count source;
|
||||
* 001 : Select the GPIO (CAP PIN) as the clock source and the falling edge as the count source
|
||||
* 010 : Select EXT_CLK_SRC1 as the clock source and the rising and falling edges as the count sources
|
||||
* 011 : Select EXT_CLK_SRC0 as the clock source and the rising and falling edges as the count sources
|
||||
* 100 : Select EXT_CLK_SRC2 as the clock source and the rising and falling edges as the count sources
|
||||
* 111 : Select the overflow of the previous timer is selected as the count source. (withString multiple timers into one 64bit counter
|
||||
* Others : system clock
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_INC_SRC_SEL(n) (((n)&0x7) << 0)
|
||||
|
||||
/***** SINPLE TIMERx CNT Register *****/
|
||||
/*!Counter register
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_CNT(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
/***** SINPLE TIMERx PERIOD Register *****/
|
||||
/*!Period register
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_PERIOD(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
/***** SINPLE TIMERx PERIOD Register *****/
|
||||
/*!Comparison value register
|
||||
*/
|
||||
#define LL_SIMPLE_TIMER_PWM(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
|
||||
|
||||
struct hgtimer_v7_hw {
|
||||
__IO uint32_t TMR_CTL;
|
||||
__IO uint32_t TMR_CNT;
|
||||
__IO uint32_t TMR_PR;
|
||||
__IO uint32_t TMR_PWM;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGTIMER_V7_HW_H */
|
||||
|
||||
|
||||
1066
sdk/driver/uart/hguart_v2.c
Normal file
1066
sdk/driver/uart/hguart_v2.c
Normal file
File diff suppressed because it is too large
Load Diff
250
sdk/driver/uart/hguart_v2_hw.h
Normal file
250
sdk/driver/uart/hguart_v2_hw.h
Normal file
@@ -0,0 +1,250 @@
|
||||
#ifndef _HGUART_V2_HW_H_
|
||||
#define _HGUART_V2_HW_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***** UARTCON *****/
|
||||
/*! RX buffer trigger threshold
|
||||
*/
|
||||
#define LL_UART_CON_RBUF_TRIG(n) (((n)&0x03) << 18)
|
||||
/*! Singal RTS_N enable
|
||||
*/
|
||||
#define LL_UART_CON_RTS_EN (1UL << 17)
|
||||
/*! Singal CTS_N enable
|
||||
*/
|
||||
#define LL_UART_CON_CTS_EN (1UL << 16)
|
||||
/*! Transmission complete interrupt enable
|
||||
*/
|
||||
#define LL_UART_CON_TCIE_EN (1UL << 15)
|
||||
/*! UART with carrier output enable.
|
||||
* @note UART0 outputs pwm of TIMER0, and UART1 outputs pwm of TIMER1.
|
||||
*/
|
||||
#define LL_UART_CON_TMR_PWM_EN (1UL << 14)
|
||||
/*! Frame error interrupt enable
|
||||
* @note A frame error refers to a low-level signal received by rx during
|
||||
* the stop bit.
|
||||
*/
|
||||
#define LL_UART_CON_FERR_IE_EN (1UL << 11)
|
||||
/*! TX buffer empty interrupt enable
|
||||
*/
|
||||
#define LL_UART_CON_TXBUF_EMPTY_IE_EN (1UL << 10)
|
||||
/*! RX buffer not empty interrupt enable
|
||||
*/
|
||||
#define LL_UART_CON_RXBUF_NEMPTY_IE_EN (1UL << 9)
|
||||
/*! Inverted TX signal
|
||||
*/
|
||||
#define LL_UART_CON_TX_INV_EN (1UL << 8)
|
||||
/*! Inverted RX signal
|
||||
*/
|
||||
#define LL_UART_CON_RX_INV_EN (1UL << 7)
|
||||
/*! Odd parity
|
||||
* @note Parity and 9bit data transfer cannot be used at the same time.
|
||||
*/
|
||||
#define LL_UART_CON_ODD_EN (1UL << 6)
|
||||
/*! parity enable
|
||||
* @note Parity and 9bit data transfer cannot be used at the same time.
|
||||
*/
|
||||
#define LL_UART_CON_PARITY_EN (1UL << 5)
|
||||
/*! 9bit data transfer enable
|
||||
* @note Parity and 9bit data transfer cannot be used at the same time.
|
||||
*/
|
||||
#define LL_UART_CON_BIT9_EN (1UL << 4)
|
||||
/*! Stop bit selection
|
||||
*/
|
||||
#define LL_UART_CON_STOP_BIT(n) (((n)&0x01) << 3)
|
||||
/*! Work mode selection
|
||||
*/
|
||||
#define LL_UART_CON_WORK_MODE(n) (((n)&0x03) << 1)
|
||||
/*! UART module enable
|
||||
*/
|
||||
#define LL_UART_CON_UART_EN (1UL << 0)
|
||||
|
||||
/***** UARTSTA *****/
|
||||
/*! Transmission complete pending
|
||||
*/
|
||||
#define LL_UART_STA_TC_PENDING (1UL << 12)
|
||||
/*! RX timeout detection pending
|
||||
* @note Only UART0 has this feature.
|
||||
*/
|
||||
#define LL_UART_STA_TO_PEND (1UL << 11)
|
||||
/*! RX parity error pending
|
||||
* @note 4 bits corrspond to 4 frame data in rx buffer.
|
||||
*/
|
||||
#define LL_UART_STA_PERR_PEND(n) (((n)>>7) & 0x0F)
|
||||
/*! The amount of data in the rx fifo
|
||||
*/
|
||||
#define LL_UART_STA_RX_CNT(n) (((n)>>4) & 0x07)
|
||||
/*! Frame error pending
|
||||
*/
|
||||
#define LL_UART_STA_FERR_PENDING (1UL << 3)
|
||||
/*! RX FIFO overflow pending
|
||||
*/
|
||||
#define LL_UART_STA_RX_BUF_OV (1UL << 2)
|
||||
/*! RX FIFO not empty pending
|
||||
*/
|
||||
#define LL_UART_STA_RX_BUF_NOT_EMPTY (1UL << 1)
|
||||
/*! TX FIFO empty pending
|
||||
*/
|
||||
#define LL_UART_STA_TX_BUF_EMPTY (1UL << 0)
|
||||
|
||||
/***** DMACON *****/
|
||||
/*! RX DMA parity error interrupt enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMACON_RX_DMA_PERR_IE_EN (1UL << 4)
|
||||
/*! RX DMA interrupt enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMACON_RX_DMA_IE_EN (1UL << 3)
|
||||
/*! TX DMA interrupt enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMACON_TX_DMA_IE_EN (1UL << 2)
|
||||
/*! RX DMA enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMACON_RX_DMA_EN (0x0101UL << 1)
|
||||
/*! TX DMA enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMACON_TX_DMA_EN (0x0101UL << 0)
|
||||
|
||||
/***** DMASTA *****/
|
||||
/*! RX DMA parity error pending
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMASTA_RX_DMA_PERR (1UL << 2)
|
||||
/*! RX DMA pending
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMASTA_RX_DMA_PEND (1UL << 1)
|
||||
/*! TX DMA pending
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_DMASTA_TX_DMA_PEND (1UL << 0)
|
||||
|
||||
/***** UART_RS485_CON *****/
|
||||
/*! RS485 RE enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_CON_RE_EN (1UL << 9)
|
||||
/*! RS485 DE enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_CON_DE_EN (1UL << 8)
|
||||
/*! RS485 work mode
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_CON_RS485_MODE(n) (((n)&0x01) << 3)
|
||||
/*! RS485 RE polarity
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_CON_RE_POL(n) (((n)&0x01) << 2)
|
||||
/*! RS485 DE polarity
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_CON_DE_POL(n) (((n)&0x01) << 1)
|
||||
/*! RS485 enable
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_CON_RS485_EN (1UL << 0)
|
||||
|
||||
/***** UART_RS485_DET *****/
|
||||
/*! The time interval between the end of STOP BIT and DE invalid. The unit
|
||||
* is the uart module clock.
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_DET_DE_DAT(n) (((n)&0x01FF) << 16)
|
||||
/*! The time interval between the time DE is valid and the START BIT is sent.
|
||||
* The unit is the uart module clock.
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_DET_DE_AT(n) (((n)&0x01FF) << 0)
|
||||
|
||||
/***** UART_RS485_TAT *****/
|
||||
/*! The time interval between the valid of RE and DE valid, the unit is the
|
||||
* uart module clock.
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_TAT_RE2DE_T(n) (((n)&0xFFFF) << 16)
|
||||
/*! The time interval between DE valid and RE valid, the unit is the uart
|
||||
* module clock.
|
||||
* @note Only UART1 has this feature
|
||||
*/
|
||||
#define LL_UART_RS485_TAT_DE2RE_T(n) (((n)&0xFFFF) << 0)
|
||||
|
||||
/***** UART_TOCON *****/
|
||||
/*! Timeout time configure
|
||||
*/
|
||||
#define LL_UART_TOCON_TO_BIT_LEN(n) (((n)&0xFFFF) << 16)
|
||||
/*! Timeout interrupt enable
|
||||
*/
|
||||
#define LL_UART_TOCON_TO_IE_EN (1UL << 1)
|
||||
/*! Timeout enable
|
||||
*/
|
||||
#define LL_UART_TOCON_TO_EN (1UL << 0)
|
||||
|
||||
typedef struct hguart_v2_hw {
|
||||
__IO uint32_t CON;
|
||||
__IO uint32_t BAUD;
|
||||
__IO uint32_t DATA;
|
||||
__IO uint32_t STA;
|
||||
__IO uint32_t TSTADR;
|
||||
__IO uint32_t RSTADR;
|
||||
__IO uint32_t TDMALEN;
|
||||
__IO uint32_t RDMALEN;
|
||||
__IO uint32_t TDMACNT;
|
||||
__IO uint32_t RDMACNT;
|
||||
__IO uint32_t DMACON;
|
||||
__IO uint32_t DMASTA;
|
||||
__IO uint32_t RS485_CON;
|
||||
__IO uint32_t RS485_DET;
|
||||
__IO uint32_t RS485_TAT;
|
||||
__IO uint32_t TOCON;
|
||||
}UART_TypeDef;
|
||||
|
||||
/**
|
||||
* @brief enable RS485 RE pin
|
||||
* @param p_uart : The structure pointer of the UART
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void ll_uart485_re_enable(UART_TypeDef *p_uart) {
|
||||
p_uart->RS485_CON |= LL_UART_RS485_CON_RE_EN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief disable RS485 RE pin
|
||||
* @param p_uart : The structure pointer of the UART
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void ll_uart485_re_disable(UART_TypeDef *p_uart) {
|
||||
p_uart->RS485_CON &= (~LL_UART_RS485_CON_RE_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief enable RS485 DE pin
|
||||
* @param p_uart : The structure pointer of the UART
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void ll_uart485_de_enable(UART_TypeDef *p_uart) {
|
||||
p_uart->RS485_CON |= LL_UART_RS485_CON_DE_EN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief disable RS485 DE pin
|
||||
* @param p_uart : The structure pointer of the UART
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void ll_uart485_de_disable(UART_TypeDef *p_uart) {
|
||||
p_uart->RS485_CON &= (~LL_UART_RS485_CON_DE_EN);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGUART_V2_HW_H_ */
|
||||
|
||||
726
sdk/driver/uart/hguart_v4.c
Normal file
726
sdk/driver/uart/hguart_v4.c
Normal file
@@ -0,0 +1,726 @@
|
||||
/**
|
||||
* @file hguart_v4.c
|
||||
* @author bxd
|
||||
* @brief simple uart
|
||||
* @version
|
||||
* TXW81X
|
||||
* @date 2023-08-02
|
||||
*
|
||||
* @copyright Copyright (c) 2023
|
||||
*
|
||||
*/
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "errno.h"
|
||||
#include "dev.h"
|
||||
#include "osal/irq.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/string.h"
|
||||
#include "hal/uart.h"
|
||||
#include "hal/gpio.h"
|
||||
#include "dev/uart/hguart_v4.h"
|
||||
#include "hguart_v4_hw.h"
|
||||
|
||||
|
||||
#define SIMPLE_UART_LOCK(mutex, flag)\
|
||||
do{\
|
||||
if(flag){\
|
||||
os_mutex_lock(mutex, osWaitForever);\
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
#define SIMPLE_UART_UNLOCK(mutex, flag)\
|
||||
do{\
|
||||
if(flag){\
|
||||
os_mutex_unlock(mutex);\
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
/* UART LOW LAYER FUNCTION */
|
||||
/**********************************************************************************/
|
||||
|
||||
static int32 hguart_v4_set_dma(struct hguart_v4 *dev, uint32 enable)
|
||||
{
|
||||
|
||||
if (enable) {
|
||||
dev->use_dma = 1;
|
||||
} else {
|
||||
dev->use_dma = 0;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
static int32 hguart_v4_dma_rx_config(struct hguart_v4_hw *p_uart, uint8 status)
|
||||
{
|
||||
uint32 _dmacon = p_uart->DMACON;
|
||||
uint32 flag = 0;
|
||||
|
||||
if (status) {
|
||||
_dmacon = 0x5;
|
||||
} else {
|
||||
_dmacon = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* fix: kick 2 times to counteract an unnecessary rx dma done
|
||||
*/
|
||||
if (p_uart->CON & LL_SIMPLE_UART_CON_DMA_IE) {
|
||||
p_uart->CON &=~ LL_SIMPLE_UART_CON_DMA_IE;
|
||||
flag = 1;
|
||||
//printf("<%x>", *(uint32 *)(0x40004b70));
|
||||
}
|
||||
|
||||
p_uart->DMACON = _dmacon;
|
||||
|
||||
__NOP();__NOP();__NOP();__NOP();
|
||||
|
||||
//printf("<%x>", *(uint32 *)(0x40004b70));
|
||||
|
||||
//clear rx done pending
|
||||
p_uart->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
|
||||
|
||||
//kick again
|
||||
p_uart->DMACON = _dmacon;
|
||||
|
||||
__NOP();__NOP();__NOP();__NOP();
|
||||
|
||||
//printf("<%x>", *(uint32 *)(0x40004b70));
|
||||
|
||||
//clear rx done pending
|
||||
p_uart->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
|
||||
|
||||
//printf("<%x>", *(uint32 *)(0x40004b70));
|
||||
|
||||
if (flag) {
|
||||
flag = 0;
|
||||
p_uart->CON |= LL_SIMPLE_UART_CON_DMA_IE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_dma_tx_config(struct hguart_v4_hw *p_uart, uint8 status)
|
||||
{
|
||||
uint32 _dmacon = p_uart->DMACON;
|
||||
|
||||
if (status) {
|
||||
_dmacon = 0xA;
|
||||
} else {
|
||||
_dmacon = 0;
|
||||
}
|
||||
|
||||
p_uart->DMACON = _dmacon;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int32 hguart_v4_set_time_out(struct hguart_v4_hw *p_uart, uint32 time_bit, uint32 enable)
|
||||
{
|
||||
|
||||
if (enable) {
|
||||
p_uart->CON |= LL_SIMPLE_UART_CON_TO_EN;
|
||||
|
||||
p_uart->TOCON = LL_SIMPLE_UART_TOCON(time_bit);
|
||||
} else {
|
||||
p_uart->CON &=~ LL_SIMPLE_UART_CON_TO_EN;
|
||||
p_uart->TOCON = 0;
|
||||
}
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
/* UART ATTCH FUNCTION */
|
||||
/**********************************************************************************/
|
||||
static int32 hguart_v4_open(struct uart_device *uart, uint32 baudrate) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if (dev->opened) {
|
||||
if (!dev->dsleep) {
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/* pin config */
|
||||
if (pin_func(dev->dev.dev.dev_id , 1) != RET_OK) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
/* reg config */
|
||||
hw->BAUD = (peripheral_clock_get(HG_APB0_PT_UART4) / baudrate) - 1;
|
||||
hw->CON = LL_SIMPLE_UART_CON_UARTEN;
|
||||
|
||||
dev->opened = 1;
|
||||
dev->irq_dma_rx = 0;
|
||||
dev->irq_dma_tx = 0;
|
||||
dev->use_dma = 0;
|
||||
dev->dsleep = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_close(struct uart_device *uart) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if (!dev->opened) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
irq_disable(dev->irq_num );
|
||||
pin_func(dev->dev.dev.dev_id, 0);
|
||||
hw->CON &= ~ LL_SIMPLE_UART_CON_UARTEN;
|
||||
|
||||
dev->opened = 0;
|
||||
dev->irq_dma_rx = 0;
|
||||
dev->irq_dma_tx = 0;
|
||||
dev->use_dma = 0;
|
||||
dev->dsleep = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_putc(struct uart_device *uart, int8 value) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
SIMPLE_UART_LOCK(&dev->mutex_tx, dev->debug_uart);
|
||||
|
||||
if (dev->opened && (hw->CON & LL_SIMPLE_UART_CON_UARTEN)) {
|
||||
while(!(hw->CON & LL_SIMPLE_UART_CON_TXBUFEMPTY));
|
||||
hw->DATA = value;
|
||||
SIMPLE_UART_UNLOCK(&dev->mutex_tx, dev->debug_uart);
|
||||
return RET_OK;
|
||||
} else {
|
||||
SIMPLE_UART_UNLOCK(&dev->mutex_tx, dev->debug_uart);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 hguart_v4_getc(struct uart_device *uart) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
SIMPLE_UART_LOCK(&dev->mutex_rx, dev->debug_uart);
|
||||
|
||||
while(!(hw->CON & LL_SIMPLE_UART_CON_RXBUFNOTEMPTY));
|
||||
hw->CON |= LL_SIMPLE_UART_CON_CLRRXDONE;
|
||||
|
||||
SIMPLE_UART_UNLOCK(&dev->mutex_rx, dev->debug_uart);
|
||||
|
||||
return hw->DATA;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_rs485_de_set(void)
|
||||
{
|
||||
if(PIN_UART4_DE != 255) {
|
||||
gpio_set_val(PIN_UART4_DE, 1);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if(PIN_UART5_DE != 255) {
|
||||
gpio_set_val(PIN_UART5_DE, 1);
|
||||
return RET_OK;
|
||||
}
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_rs485_de_reset(void)
|
||||
{
|
||||
if(PIN_UART4_DE != 255) {
|
||||
gpio_set_val(PIN_UART4_DE, 0);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if(PIN_UART5_DE != 255) {
|
||||
gpio_set_val(PIN_UART5_DE, 0);
|
||||
return RET_OK;
|
||||
}
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_rs485_re_set(void)
|
||||
{
|
||||
if(PIN_UART4_RE != 255) {
|
||||
gpio_set_val(PIN_UART4_RE, 1);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if(PIN_UART5_RE != 255) {
|
||||
gpio_set_val(PIN_UART5_RE, 1);
|
||||
return RET_OK;
|
||||
}
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_rs485_re_reset(void)
|
||||
{
|
||||
if(PIN_UART4_RE != 255) {
|
||||
gpio_set_val(PIN_UART4_RE, 0);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if(PIN_UART5_RE != 255) {
|
||||
gpio_set_val(PIN_UART5_RE, 0);
|
||||
return RET_OK;
|
||||
}
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_puts(struct uart_device *uart, uint8 *buf, uint32 size) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
uint32 i = 0;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
SIMPLE_UART_LOCK(&dev->mutex_tx, dev->debug_uart);
|
||||
|
||||
if (dev->use_dma) {
|
||||
if (dev->debug_uart) {
|
||||
//enable uart 1Byte tx done irq
|
||||
hw->CON |= LL_SIMPLE_UART_CON_UARTTXIE;
|
||||
|
||||
dev->p_tx_buf = (uint8 *)buf;
|
||||
dev->tx_total_byte = size;
|
||||
dev->tx_cur_byte = 0;
|
||||
|
||||
//send 1Byte to trigger 1Byte tx done irq
|
||||
hw->DATA = buf[0];
|
||||
|
||||
os_sema_down(&dev->sema_tx, osWaitForever);
|
||||
|
||||
//disable uart 1Byte tx done irq
|
||||
hw->CON &=~ LL_SIMPLE_UART_CON_UARTTXIE;
|
||||
} else if (dev->rs485_set) {
|
||||
hguart_v4_dma_tx_config(hw, 0);
|
||||
hw->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
|
||||
|
||||
hguart_v4_rs485_de_set();
|
||||
hguart_v4_rs485_re_set();
|
||||
|
||||
hw->DMAADR = (uint32)buf;
|
||||
hw->DMALEN = size;
|
||||
hguart_v4_dma_tx_config(hw, 1);
|
||||
|
||||
/* waiting for tx done */
|
||||
while (!(hw->CON & LL_SIMPLE_UART_CON_DMAPEND));
|
||||
|
||||
hguart_v4_rs485_re_reset();
|
||||
hguart_v4_rs485_de_reset();
|
||||
} else {
|
||||
for (i = 0; i < size; i++) {
|
||||
hguart_v4_putc(uart, buf[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < size; i++) {
|
||||
hguart_v4_putc(uart, buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SIMPLE_UART_UNLOCK(&dev->mutex_tx, dev->debug_uart);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_gets(struct uart_device *uart, uint8 *buf, uint32 size) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
uint32 i = 0;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
SIMPLE_UART_LOCK(&dev->mutex_rx, dev->debug_uart);
|
||||
|
||||
if (dev->use_dma) {
|
||||
hw->DMAADR = (uint32)buf;
|
||||
hw->DMALEN = size;
|
||||
hguart_v4_dma_rx_config(hw, 1);
|
||||
} else {
|
||||
for (i = 0; i < size; i++) {
|
||||
hguart_v4_getc(uart);
|
||||
}
|
||||
}
|
||||
|
||||
SIMPLE_UART_UNLOCK(&dev->mutex_rx, dev->debug_uart);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_ioctl(struct uart_device *uart, enum uart_ioctl_cmd ioctl_cmd, uint32 param1, uint32 param2) {
|
||||
|
||||
int32 ret_val = RET_OK;
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
switch (ioctl_cmd) {
|
||||
case (UART_IOCTL_CMD_USE_DMA):
|
||||
ret_val = hguart_v4_set_dma(dev, param1);
|
||||
break;
|
||||
case (UART_IOCTL_CMD_SET_TIME_OUT):
|
||||
ret_val = hguart_v4_set_time_out((struct hguart_v4_hw *)dev->hw, param1, param2);
|
||||
break;
|
||||
case (UART_IOCTL_CMD_DISABLE_DEBUG_SELECTION):
|
||||
dev->debug_uart = (param1) ? (1) : (0);
|
||||
ret_val = RET_OK;
|
||||
break;
|
||||
case (UART_IOCTL_CMD_SET_RS485_EN):
|
||||
dev->rs485_set = (param1) ? (1) : (0);
|
||||
ret_val = RET_OK;
|
||||
break;
|
||||
default:
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* interrupt handler */
|
||||
static void hguart_v4_irq_handler(void *data) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)data;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if ((hw->CON & LL_SIMPLE_UART_CON_UARTTXIE) && (hw->CON & LL_SIMPLE_UART_CON_TXDONE)) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_CLRTXDONE;
|
||||
|
||||
dev->tx_cur_byte++;
|
||||
//printf("cur len:%d\r\n", dev->tx_cur_byte);
|
||||
if (dev->tx_cur_byte == dev->tx_total_byte) {
|
||||
//printf("up\r\n");
|
||||
os_sema_up(&dev->sema_tx);
|
||||
//diable uart tx 1byte done irq
|
||||
hw->CON &=~ LL_SIMPLE_UART_CON_UARTTXIE;
|
||||
} else {
|
||||
hw->DATA = dev->p_tx_buf[dev->tx_cur_byte];
|
||||
}
|
||||
}
|
||||
|
||||
if ((hw->CON & LL_SIMPLE_UART_CON_UARTRXIE) && (hw->CON & LL_SIMPLE_UART_CON_RXBUFNOTEMPTY)) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_CLRRXDONE;
|
||||
if (dev->irq_hdl) {
|
||||
dev->irq_hdl(UART_IRQ_FLAG_RX_BYTE, dev->irq_data, hw->DATA, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((hw->CON & LL_SIMPLE_UART_CON_FERRIE) && (hw->CON & LL_SIMPLE_UART_CON_FERR)) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_CLRFERR;
|
||||
if (dev->irq_hdl) {
|
||||
dev->irq_hdl(UART_IRQ_FLAG_FRAME_ERR, dev->irq_data, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//UART4/5 TIMEOUT来了之后,DMA DONE也会起来,故DMA DONE中断之前要判断是否TIMEOUT
|
||||
if (!(hw->CON & LL_SIMPLE_UART_CON_TO_PENDING)) {
|
||||
if ((hw->CON & LL_SIMPLE_UART_CON_DMA_IE) && (hw->CON & LL_SIMPLE_UART_CON_DMAPEND)) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
|
||||
if (dev->irq_hdl) {
|
||||
if (dev->irq_dma_rx) {
|
||||
dev->irq_hdl(UART_IRQ_FLAG_DMA_RX_DONE, dev->irq_data, hw->DMACNT, 0);
|
||||
} else {
|
||||
dev->irq_hdl(UART_IRQ_FLAG_DMA_TX_DONE, dev->irq_data, hw->DMACNT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((hw->CON & LL_SIMPLE_UART_CON_TO_IE) && (hw->CON & LL_SIMPLE_UART_CON_TO_PENDING)) {
|
||||
hw->CON |= (LL_SIMPLE_UART_CON_CLRTOPEND | LL_SIMPLE_UART_CON_CLRDMAPEND);
|
||||
if (dev->irq_hdl) {
|
||||
dev->irq_hdl(UART_IRQ_FLAG_TIME_OUT, dev->irq_data, hw->DMACNT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* request interrupt */
|
||||
static int32 hguart_v4_request_irq(struct uart_device *uart, uart_irq_hdl irqhdl, uint32 irq_flag, uint32 data) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
dev->irq_hdl = irqhdl;
|
||||
dev->irq_data = data ;
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_RX_BYTE) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_UARTRXIE;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_FRAME_ERR) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_FERRIE;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_DMA_RX_DONE) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_DMA_IE;
|
||||
dev->irq_dma_tx = 0;
|
||||
dev->irq_dma_rx = 1;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_DMA_TX_DONE) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_DMA_IE;
|
||||
dev->irq_dma_tx = 1;
|
||||
dev->irq_dma_rx = 0;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_TIME_OUT) {
|
||||
hw->CON |= LL_SIMPLE_UART_CON_TO_IE;
|
||||
}
|
||||
|
||||
#if defined(TXW81X)
|
||||
irq_enable(dev->comm_irq_num);
|
||||
#elif defined(TXW82X)
|
||||
irq_enable(dev->irq_num);
|
||||
#endif
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int32 hguart_v4_release_irq(struct uart_device *uart, uint32 irq_flag) {
|
||||
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if ((!dev->opened) || (dev->dsleep)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_RX_BYTE) {
|
||||
hw->CON &= ~ LL_SIMPLE_UART_CON_UARTRXIE;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_FRAME_ERR) {
|
||||
hw->CON &= ~ LL_SIMPLE_UART_CON_FERRIE;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_DMA_RX_DONE) {
|
||||
hw->CON &=~ LL_SIMPLE_UART_CON_DMA_IE;
|
||||
}
|
||||
|
||||
if (irq_flag & UART_IRQ_FLAG_TIME_OUT) {
|
||||
hw->CON &=~ LL_SIMPLE_UART_CON_TO_IE;
|
||||
}
|
||||
|
||||
#if defined(TXW81X)
|
||||
irq_disable(dev->comm_irq_num);
|
||||
#elif defined(TXW82X)
|
||||
irq_disable(dev->irq_num);
|
||||
#endif
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SLEEP
|
||||
int32 hguart_v4_suspend(struct dev_obj *obj)
|
||||
{
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)obj;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
|
||||
if (!dev->opened) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if (0 > os_mutex_lock(&dev->bp_suspend_lock, 10000)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Close the UART
|
||||
*/
|
||||
hw->CON &= ~ BIT(4);
|
||||
|
||||
|
||||
// pin_func(dev->dev.dev.dev_id, 0);
|
||||
|
||||
#if defined(TXW81X)
|
||||
irq_disable(dev->comm_irq_num);
|
||||
#elif defined(TXW82X)
|
||||
irq_disable(dev->irq_num);
|
||||
#endif
|
||||
/*
|
||||
* clear pending
|
||||
*/
|
||||
hw->CON |= 0x3f000000;
|
||||
|
||||
|
||||
os_memset((void *)&dev->bp_regs, 0, sizeof(dev->bp_regs));
|
||||
|
||||
/*
|
||||
* save the reglist
|
||||
*/
|
||||
dev->bp_regs.con = hw->CON;
|
||||
dev->bp_regs.baud = hw->BAUD;
|
||||
dev->bp_regs.tocon = hw->TOCON;
|
||||
dev->bp_regs.dmaadr = hw->DMAADR;
|
||||
dev->bp_regs.dmalen = hw->DMALEN;
|
||||
dev->bp_regs.dmacon = hw->DMACON;
|
||||
|
||||
/*
|
||||
* save the irq_hdl created by user
|
||||
*/
|
||||
dev->bp_irq_hdl = dev->irq_hdl;
|
||||
dev->bp_irq_data = dev->irq_data;
|
||||
|
||||
//venus v2:uart4&5 clk and uart0 clk are share the same source
|
||||
if (UART4_BASE == (uint32)hw) {
|
||||
// sysctrl_uart4_clk_close();
|
||||
} else if (UART5_BASE == (uint32)hw) {
|
||||
// sysctrl_uart5_clk_close();
|
||||
}
|
||||
|
||||
dev->dsleep = 1;
|
||||
|
||||
os_mutex_unlock(&dev->bp_suspend_lock);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int32 hguart_v4_resume(struct dev_obj *obj)
|
||||
{
|
||||
struct hguart_v4 *dev = (struct hguart_v4 *)obj;
|
||||
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
|
||||
if (!dev->opened) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if (0 > os_mutex_lock(&dev->bp_resume_lock, 10000)) {
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
/* pin config */
|
||||
// if (pin_func(dev->dev.dev.dev_id, 1) != RET_OK) {
|
||||
// return RET_ERR;
|
||||
// }
|
||||
|
||||
|
||||
/*
|
||||
* recovery the UART clk
|
||||
*/
|
||||
if (UART4_BASE == (uint32)hw) {
|
||||
// sysctrl_uart4_clk_open();
|
||||
} else if (UART5_BASE == (uint32)hw) {
|
||||
// sysctrl_uart5_clk_open();
|
||||
}
|
||||
|
||||
/*
|
||||
* recovery the reglist from sram
|
||||
*/
|
||||
hw->CON = dev->bp_regs.con;
|
||||
hw->BAUD = dev->bp_regs.baud;
|
||||
hw->TOCON = dev->bp_regs.tocon;
|
||||
hw->DMAADR = dev->bp_regs.dmaadr;
|
||||
hw->DMALEN = dev->bp_regs.dmalen;
|
||||
hw->DMACON = dev->bp_regs.dmacon;
|
||||
|
||||
/*
|
||||
* recovery the irq handle and data
|
||||
*/
|
||||
dev->irq_hdl = dev->bp_irq_hdl;
|
||||
dev->irq_data = dev->bp_irq_data;
|
||||
|
||||
os_memset((void *)&dev->bp_regs, 0, sizeof(dev->bp_regs));
|
||||
|
||||
/*!
|
||||
* Open the UART
|
||||
*/
|
||||
hw->CON |= BIT(4);
|
||||
if (hw->DMACON & 1) {
|
||||
hguart_v4_dma_rx_config(hw, 1);
|
||||
}
|
||||
|
||||
#if defined(TXW81X)
|
||||
irq_enable(dev->comm_irq_num);
|
||||
#elif defined(TXW82X)
|
||||
irq_enable(dev->irq_num);
|
||||
#endif
|
||||
dev->dsleep = 0;
|
||||
|
||||
os_mutex_unlock(&dev->bp_resume_lock);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct uart_hal_ops uart_v4_ops = {
|
||||
.open = hguart_v4_open,
|
||||
.close = hguart_v4_close,
|
||||
.getc = hguart_v4_getc,
|
||||
.putc = hguart_v4_putc,
|
||||
.gets = hguart_v4_gets,
|
||||
.puts = hguart_v4_puts,
|
||||
.ioctl = hguart_v4_ioctl,
|
||||
.request_irq = hguart_v4_request_irq,
|
||||
.release_irq = hguart_v4_release_irq,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hguart_v4_suspend,
|
||||
.ops.resume = hguart_v4_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
int32 hguart_v4_attach(uint32 dev_id, struct hguart_v4 *uart) {
|
||||
|
||||
uart->irq_data = 0;
|
||||
uart->irq_hdl = NULL;
|
||||
uart->opened = 0;
|
||||
uart->irq_dma_rx = 0;
|
||||
uart->irq_dma_tx = 0;
|
||||
uart->use_dma = 0;
|
||||
uart->debug_uart = 0;
|
||||
uart->rs485_set = 0;
|
||||
uart->dsleep = 0;
|
||||
uart->p_tx_buf = NULL;
|
||||
uart->tx_cur_byte = 0;
|
||||
uart->tx_total_byte = 0;
|
||||
uart->dev.dev.ops = (const struct devobj_ops *)&uart_v4_ops;
|
||||
|
||||
os_sema_init(&uart->sema_tx, 0);
|
||||
os_mutex_init(&uart->mutex_rx);
|
||||
os_mutex_init(&uart->mutex_tx);
|
||||
#ifdef CONFIG_SLEEP
|
||||
os_mutex_init(&uart->bp_suspend_lock);
|
||||
os_mutex_init(&uart->bp_resume_lock);
|
||||
#endif
|
||||
|
||||
request_irq(uart->irq_num, hguart_v4_irq_handler, uart);
|
||||
|
||||
dev_register(dev_id, (struct dev_obj *)uart);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
164
sdk/driver/uart/hguart_v4_hw.h
Normal file
164
sdk/driver/uart/hguart_v4_hw.h
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef _HGUART_V4_HW_H_
|
||||
#define _HGUART_V4_HW_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/***** UARTCON *****/
|
||||
/*! Timeout interrupt en
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_TO_IE (1UL << 31)
|
||||
|
||||
/*! Timeout function en
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_TO_EN (1UL << 30)
|
||||
|
||||
/*! Timeout pending
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CLRTOPEND (1UL << 29)
|
||||
|
||||
/*! Transmission completed The 1byte flag was cleared to zero
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CLRTXDONE (1UL << 28)
|
||||
/*! The frame receiving error detection flag is cleared to zero
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CLRFERR (1UL << 27)
|
||||
/*! The receive cache register is not null flag cleared
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CLRRXDONE (1UL << 26)
|
||||
/*! DMA interrupt flag cleared to zero
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CLRDMAPEND (1UL << 25)
|
||||
/*! Receive address interrupt flag cleared to zero
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CLRRXADDRPEND (1UL << 24)
|
||||
/*! Transmission completed 1byte flag. This bit is 0 when the module is disabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_TXDONE (1UL << 21)
|
||||
/*! Frame receiving error detection flag
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_FERR (1UL << 20)
|
||||
/*! Receive cache register is not empty flag, this bit is 0 when the module is not enabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_RXBUFNOTEMPTY (1UL << 19)
|
||||
/*! The send cache register is an empty flag. This bit is 0 when the module is disabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_TXBUFEMPTY (1UL << 18)
|
||||
/*! The DMA completion flag bit, which is set to 1 when a send or receive is complete using DMA
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_DMAPEND (1UL << 17)
|
||||
/*! Receive address interrupt flag RXADDRPEND
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_RXADDRPEND (1UL << 16)
|
||||
|
||||
/*! RX_TIMEOUT PENDING
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_TO_PENDING (1UL << 15)
|
||||
|
||||
/*! Select UART output with which PWM carrier:
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_CARRIER_SEL(n) (((n)&0x09) << 11)
|
||||
/*! Set the CARRIER_SEL bit to the PWM carrier mode enable bit. Specify the carrier_sel bit for the specific PWM carrier of the TIMER
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_PWM_CARRIER_EN (1UL << 10)
|
||||
/*! The receiving address was interrupted. Procedure
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_RXADDRIE (1UL << 9)
|
||||
/*! Error detection interrupt enabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_FERRIE (1UL << 8)
|
||||
/*! DMA interrupt enabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_DMA_IE (1UL << 7)
|
||||
/*! Stop bit setting
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_STOPBIT (1UL << 6)
|
||||
/*! The 9bit function was enabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_BIT9EN (1UL << 5)
|
||||
/*! The Uart function was enabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_UARTEN (1UL << 4)
|
||||
/*! Send data inversely
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_TXINV (1UL << 3)
|
||||
/*! The received data is reversed
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_RXINV (1UL << 2)
|
||||
/*! Send 1byte to enable the interrupt
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_UARTTXIE (1UL << 1)
|
||||
/*! The receiving interrupt function was enabled
|
||||
*/
|
||||
#define LL_SIMPLE_UART_CON_UARTRXIE (1UL << 0)
|
||||
|
||||
|
||||
|
||||
|
||||
/***** UARTBAUD *****/
|
||||
/*! Baud rate setting
|
||||
*/
|
||||
#define LL_SIMPLE_UART_UARTBAUD(n) (((n)&0x0003FFFF) << 0)
|
||||
|
||||
|
||||
|
||||
/***** UARTDATA *****/
|
||||
/*! Data register
|
||||
*/
|
||||
#define LL_SIMPLE_UART_UARTDATA(n) (((n)&0x000000FF) << 0)
|
||||
|
||||
|
||||
/***** UARTTOCON *****/
|
||||
/*! TOCON register
|
||||
*/
|
||||
#define LL_SIMPLE_UART_TOCON(n) (((n)&0x0000FFFF) << 0)
|
||||
|
||||
|
||||
/***** UARTDMAADR *****/
|
||||
/*! DMAADR register
|
||||
*/
|
||||
#define LL_SIMPLE_UART_UARTDMAADR(n) (((n)&0xFFFFFFFF) << 0)
|
||||
|
||||
|
||||
|
||||
/***** UARTDMALEN *****/
|
||||
/*! DMALEN register
|
||||
*/
|
||||
#define LL_SIMPLE_UART_UARTDMALEN(n) (((n)&0x000007FF) << 0)
|
||||
|
||||
|
||||
|
||||
/***** UARTDMACON *****/
|
||||
/*!DMACON register
|
||||
*/
|
||||
#define LL_SIMPLE_UART_UART_TX_USEDMA_KEY (1UL << 3)
|
||||
#define LL_SIMPLE_UART_UART_RX_USEDMA_KEY (1UL << 2)
|
||||
#define LL_SIMPLE_UART_UART_TX_USEDMA (1UL << 1)
|
||||
#define LL_SIMPLE_UART_UART_RX_USEDMA (1UL << 0)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Simple Universal Synchronous Asynchronous Receiver Transmitter
|
||||
*/
|
||||
|
||||
struct hguart_v4_hw{
|
||||
__IO uint32_t CON;
|
||||
__IO uint32_t BAUD;
|
||||
__IO uint32_t DATA;
|
||||
__IO uint32_t TOCON;
|
||||
__IO uint32_t DMAADR;
|
||||
__IO uint32_t DMALEN;
|
||||
__IO uint32_t DMACON;
|
||||
__IO uint32_t DMACNT;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HGUART_V4_HW_H_ */
|
||||
|
||||
838
sdk/driver/vpp/hgvpp_v3.c
Normal file
838
sdk/driver/vpp/hgvpp_v3.c
Normal file
@@ -0,0 +1,838 @@
|
||||
#include "typesdef.h"
|
||||
#include "errno.h"
|
||||
#include "osal/irq.h"
|
||||
#include "devid.h"
|
||||
#include "dev/vpp/hgvpp.h"
|
||||
#include "osal/string.h"
|
||||
|
||||
struct hgvpp_hw
|
||||
{
|
||||
__IO uint32_t CON;
|
||||
__IO uint32_t CON1;
|
||||
__IO uint32_t SIZE;
|
||||
__IO uint32_t DLT;
|
||||
__IO uint32_t DHT;
|
||||
__IO uint32_t STA;
|
||||
__IO uint32_t DMA_YADR;
|
||||
__IO uint32_t DMA_UADR;
|
||||
__IO uint32_t DMA_VADR;
|
||||
__IO uint32_t DMA_YADR1;
|
||||
__IO uint32_t DMA_UADR1;
|
||||
__IO uint32_t DMA_VADR1;
|
||||
__IO uint32_t IWM0_CON;
|
||||
__IO uint32_t IWM0_CON1;
|
||||
__IO uint32_t IWM0_SIZE;
|
||||
__IO uint32_t IWM0_YUV;
|
||||
__IO uint32_t IWM0_YUV1;
|
||||
__IO uint32_t IWM0_LADR;
|
||||
__IO uint32_t IWM0_HADR;
|
||||
__IO uint32_t IWM0_IDX0;
|
||||
__IO uint32_t IWM0_IDX1;
|
||||
__IO uint32_t IWM0_IDX2;
|
||||
__IO uint32_t IWM1_CON;
|
||||
__IO uint32_t IWM1_SIZE;
|
||||
__IO uint32_t IWM1_YUV;
|
||||
__IO uint32_t IWM1_LADR;
|
||||
__IO uint32_t IPF_SADR;
|
||||
__IO uint32_t MD_CON;
|
||||
__IO uint32_t MD_WIN_CON0;
|
||||
__IO uint32_t MD_WIN_CON1;
|
||||
__IO uint32_t MD_BASE_ADDR;
|
||||
__IO uint32_t ITP_PSRAM_YADR;
|
||||
__IO uint32_t ITP_PSRAM_UADR;
|
||||
__IO uint32_t ITP_PSRAM_VADR;
|
||||
__IO uint32_t FRM_PSRAM_YCNT;
|
||||
__IO uint32_t FRM_PSRAM_UVCNT;
|
||||
__IO uint32_t FRM1_PSRAM_YCNT;
|
||||
__IO uint32_t FRM1_PSRAM_UVCNT;
|
||||
};
|
||||
|
||||
|
||||
vpp_irq_hdl vppirq_vector_table[VPP_IRQ_NUM];
|
||||
volatile uint32 vppirq_dev_table[VPP_IRQ_NUM];
|
||||
|
||||
extern volatile uint8 isp_ov_err;
|
||||
|
||||
static int32 hgvpp_ioctl(struct vpp_device *p_vpp, enum vpp_ioctl_cmd ioctl_cmd, uint32 param1, uint32 param2)
|
||||
{
|
||||
int32 ret_val = RET_OK;
|
||||
uint32 w,h,num;
|
||||
uint32 x_s,y_s,x_e,y_e;
|
||||
//uint32 *size_array;
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
switch(ioctl_cmd){
|
||||
case VPP_IOCTL_CMD_ITP_AUTO_CLOSE:
|
||||
if(param1)
|
||||
hw->CON &= ~BIT(30);
|
||||
else
|
||||
hw->CON |= BIT(30);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_ITP_Y_ADDR:
|
||||
hw->ITP_PSRAM_YADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_ITP_U_ADDR:
|
||||
hw->ITP_PSRAM_UADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_ITP_V_ADDR:
|
||||
hw->ITP_PSRAM_VADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_ITP_EN:
|
||||
if(param1)
|
||||
hw->CON |= BIT(29);
|
||||
else
|
||||
hw->CON &= ~BIT(29);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_TAKE_PHOTO_LINEBUF:
|
||||
if(param1 < 8){
|
||||
hw->CON1 &= ~(0x7<<10);
|
||||
hw->CON1 |= (param1<<10);
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_DIS_UV_MODE:
|
||||
if(param1)
|
||||
hw->CON |= BIT(4);
|
||||
else
|
||||
hw->CON &= ~BIT(4);
|
||||
|
||||
if(param2){
|
||||
hw->CON1 |= BIT(5);
|
||||
}else{
|
||||
hw->CON1 &= ~BIT(5);
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_THRESHOLD:
|
||||
hw->DLT = param1;
|
||||
hw->DHT = param2;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_RC:
|
||||
if(param1)
|
||||
hw->IWM0_CON |= BIT(5);
|
||||
else
|
||||
hw->IWM0_CON &= ~BIT(5);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_RC:
|
||||
if(param1)
|
||||
hw->IWM1_CON |= BIT(5);
|
||||
else
|
||||
hw->IWM1_CON &= ~BIT(5);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_COLOR:
|
||||
hw->IWM0_YUV = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_COLOR:
|
||||
hw->IWM1_YUV = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_BMPADR:
|
||||
hw->IWM0_LADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_BMPADR:
|
||||
hw->IWM1_LADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_LOCATED:
|
||||
hw->IWM0_CON &= ~(0x1ff<<15);
|
||||
hw->IWM0_CON &= ~(0xff<<24);
|
||||
hw->IWM0_CON |= (((param1&0Xff00)>>8)<<24);
|
||||
hw->IWM0_CON |= ((param1&0Xff)<<15);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_LOCATED:
|
||||
hw->IWM1_CON &= ~(0xff<<16);
|
||||
hw->IWM1_CON &= ~(0xff<<24);
|
||||
hw->IWM1_CON |= (((param1&0Xff00)>>8)<<24);
|
||||
hw->IWM1_CON |= ((param1&0Xff)<<16);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_CONTRAST:
|
||||
hw->IWM0_CON &= ~(0x7<<2);
|
||||
hw->IWM0_CON |= (param1<<2);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_CONTRAST:
|
||||
|
||||
hw->IWM1_CON &= ~(0x7<<2);
|
||||
hw->IWM1_CON |= (param1<<2);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_CHAR_SIZE_AND_NUM:
|
||||
w = param1&0xff;
|
||||
h = ((param1&0xff00)>>8)&0xff;
|
||||
num = param2&0xff;
|
||||
hw->IWM0_SIZE &= ~(0x1f<<0);
|
||||
hw->IWM0_SIZE |= (num<<0);
|
||||
hw->IWM0_SIZE &= ~(0x3f<<5);
|
||||
hw->IWM0_SIZE |= (w<<5);
|
||||
hw->IWM0_SIZE &= ~(0x3ff<<12);
|
||||
hw->IWM0_SIZE |= ((w*num)<<12);
|
||||
hw->IWM0_SIZE &= ~(0xff<<23);
|
||||
hw->IWM0_SIZE |= (h<<23);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_CHAR_IDX:
|
||||
if(param2 > 23)
|
||||
return ret_val;
|
||||
|
||||
if(param2 < 8){
|
||||
hw->IWM0_IDX0 &= ~(0xf<<(param2*4));
|
||||
hw->IWM0_IDX0 |= (param1<<(param2*4));
|
||||
}
|
||||
else if(param2 < 16){
|
||||
hw->IWM0_IDX1 &= ~(0xf<<((param2-8)*4));
|
||||
hw->IWM0_IDX1 |= (param1<<((param2-8)*4));
|
||||
|
||||
}else{
|
||||
hw->IWM0_IDX2 &= ~(0xf<<((param2-16)*4));
|
||||
hw->IWM0_IDX2 |= (param1<<((param2-16)*4));
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_PHOTO_SIZE:
|
||||
w = param1&0xff;
|
||||
h = ((param1&0xff00)>>8)&0xff;
|
||||
|
||||
hw->IWM1_SIZE &= ~(0xff<<12);
|
||||
hw->IWM1_SIZE |= (w<<12);
|
||||
hw->IWM1_SIZE &= ~(0xff<<23);
|
||||
hw->IWM1_SIZE |= (h<<23);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_MODE:
|
||||
if(param1)
|
||||
hw->IWM0_CON |= BIT(1);
|
||||
else
|
||||
hw->IWM0_CON &= ~BIT(1);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_MODE:
|
||||
if(param1)
|
||||
hw->IWM1_CON |= BIT(1);
|
||||
else
|
||||
hw->IWM1_CON &= ~BIT(1);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_EN:
|
||||
if(param1)
|
||||
hw->IWM0_CON |= BIT(0);
|
||||
else
|
||||
hw->IWM0_CON &= ~BIT(0);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK1_EN:
|
||||
if(param1)
|
||||
hw->IWM1_CON |= BIT(0);
|
||||
else
|
||||
hw->IWM1_CON &= ~BIT(0);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_DET_EN:
|
||||
if(param1){
|
||||
//hw->MD_CON &= ~(0x1f<<18);
|
||||
//hw->MD_CON |= (BIT(23));
|
||||
hw->MD_CON |= BIT(0);
|
||||
}
|
||||
else{
|
||||
hw->MD_CON &= ~BIT(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_ALL_FRAME_OR_WINDOW:
|
||||
if(param1 == 0){
|
||||
hw->MD_CON |= (BIT(26));
|
||||
}
|
||||
else{
|
||||
hw->MD_CON &= ~BIT(26);
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_CALBUF:
|
||||
hw->MD_BASE_ADDR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_RANGE:
|
||||
x_s = param1&0xfff;
|
||||
y_s = ((param1&0xfff0000)>>16)&0xfff;
|
||||
x_e = param2&0xfff;
|
||||
y_e = ((param2&0xfff0000)>>16)&0xfff;
|
||||
//hw->MD_WIN_CON0 = param1;
|
||||
//hw->MD_WIN_CON1 = param1;
|
||||
hw->MD_WIN_CON0 = (x_s | (y_s<<16));
|
||||
hw->MD_WIN_CON1 = ((x_e-1) | ((y_e-1)<<16));
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_BLK_THRESHOLD:
|
||||
param1 = param1&0xff;
|
||||
hw->MD_CON &= ~(0xff<<1);
|
||||
hw->MD_CON |= (param1<<1);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_FRAME_THRESHOLD:
|
||||
param1 = param1&0xfff;
|
||||
hw->MD_CON &= ~(0xfff<<9);
|
||||
hw->MD_CON |= (param1<<9);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MOTION_FRAME_INTERVAL:
|
||||
param1 = param1&0x1f;
|
||||
hw->MD_CON &= ~(0x1f<<21);
|
||||
hw->MD_CON |= (param1<<21);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_IFP_ADDR:
|
||||
hw->IPF_SADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_IFP_EN:
|
||||
if(param1){
|
||||
hw->CON |= BIT(28);
|
||||
}
|
||||
else{
|
||||
hw->CON &= ~BIT(28);
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_MODE:
|
||||
if(param1){
|
||||
hw->CON |= BIT(1);
|
||||
//os_printf("vpp input raw or rgb888\r\n");
|
||||
}
|
||||
else{
|
||||
hw->CON &= ~BIT(1);
|
||||
//os_printf("vpp input YUV422\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_SIZE:
|
||||
w = param1;
|
||||
h = param2;
|
||||
|
||||
if(w%16 != 0){
|
||||
os_printf("###############################warning image_w no align 16 Byte##################################################\r\n");
|
||||
}
|
||||
|
||||
if(h%8 != 0){
|
||||
os_printf("###############################warning image_h no align 8 Byte##################################################\r\n");
|
||||
}
|
||||
hw->SIZE = (h<<12) | (w<<0);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_YCBCR:
|
||||
if(param1 > 3){
|
||||
os_printf("set ycbcr error:%d\r\n",param1);
|
||||
}
|
||||
hw->CON &= ~(BIT(2)|BIT(3));
|
||||
hw->CON |= param1<<2;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF0_CNT:
|
||||
if(param1 > 16){
|
||||
os_printf("set buf0 error:%d\r\n",param1);
|
||||
}
|
||||
hw->CON &= ~(0x0f<<9);
|
||||
hw->CON |= (param1<<9);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF1_CNT:
|
||||
if(param1 > 16){
|
||||
os_printf("set buf1 error:%d\r\n",param1);
|
||||
}
|
||||
hw->CON1 &= ~(0x0f<<6);
|
||||
hw->CON1 |= (param1<<6);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF0_EN:
|
||||
if(param1)
|
||||
hw->CON |= BIT(8);
|
||||
else
|
||||
hw->CON &= ~BIT(8);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF1_EN:
|
||||
if(param1)
|
||||
hw->CON1 |= BIT(1);
|
||||
else
|
||||
hw->CON1 &= ~BIT(1);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_FTUSB3_EN:
|
||||
if(param1)
|
||||
hw->CON1 |= BIT(0);
|
||||
else
|
||||
hw->CON1 &= ~BIT(0);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF1_SHRINK:
|
||||
hw->CON1 &= ~(0x07<<2);
|
||||
hw->CON1 |= (param1<<2); //0: 1/2
|
||||
//1: 1/3
|
||||
//2: 1/4
|
||||
//3: 1/6
|
||||
//4: 2/3
|
||||
//5: 1/1
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_INPUT_INTERFACE:
|
||||
hw->CON &= ~(0x07<<5);
|
||||
hw->CON |= (param1<<5);
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF0_Y_ADDR:
|
||||
hw->DMA_YADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF0_U_ADDR:
|
||||
hw->DMA_UADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF0_V_ADDR:
|
||||
hw->DMA_VADR = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF1_Y_ADDR:
|
||||
hw->DMA_YADR1 = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF1_U_ADDR:
|
||||
hw->DMA_UADR1 = param1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_BUF1_V_ADDR:
|
||||
hw->DMA_VADR1 = param1;
|
||||
break;
|
||||
|
||||
// case VPP_IOCTL_CMD_ISP_CONFIG:
|
||||
// hw->CON = 0;
|
||||
// hw->CON |= 0x3 << 20;
|
||||
// hw->CON |= 0x3 << 5;
|
||||
// hw->CON |= 0x1 << 1;
|
||||
// hw->CON1 |= 0x1 << 0;
|
||||
// hw->CON |= BIT(0);
|
||||
// break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_STA:
|
||||
ret_val = hw->STA;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_PSRAM_YCNT:
|
||||
w = param1;
|
||||
h = param2;
|
||||
hw->FRM_PSRAM_YCNT = (w*h)/4 -1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_PSRAM_UVCNT:
|
||||
w = param1;
|
||||
h = param2;
|
||||
hw->FRM_PSRAM_UVCNT = (w*h)/16 -1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_PSRAM1_YCNT:
|
||||
w = param1;
|
||||
h = param2;
|
||||
hw->FRM1_PSRAM_YCNT = (w*h)/4 -1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_PSRAM1_UVCNT:
|
||||
w = param1;
|
||||
h = param2;
|
||||
hw->FRM1_PSRAM_UVCNT = (w*h)/16 -1;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_FRAME_SAVE_NO_SRAM:
|
||||
hw->CON1 &= ~(3<<13);
|
||||
if(param1 == 1){
|
||||
hw->CON1 |= (1<<13);
|
||||
}else if(param1 == 2){
|
||||
hw->CON1 |= (2<<13);
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_F1_SAVE_NO_SRAM:
|
||||
if(param1 == 1){ //frame1 save
|
||||
hw->CON1 |= BIT(15); //enable
|
||||
}else{
|
||||
hw->CON1 &= ~BIT(15); //disable
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_F0_IS_PSRAM:
|
||||
if((hw->CON1 & (3<<13)) == (1<<13)){
|
||||
ret_val = 1;
|
||||
}else{
|
||||
ret_val = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_F1_IS_PSRAM:
|
||||
if((hw->CON1 & (3<<13)) == (2<<13)){
|
||||
ret_val = 1;
|
||||
}else if((hw->CON1 & BIT(15)) == BIT(15)){
|
||||
ret_val = 1;
|
||||
}else{
|
||||
ret_val = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_F0_IS_ENABLE:
|
||||
if(hw->CON&BIT(8)){
|
||||
ret_val = 1;
|
||||
}else{
|
||||
ret_val = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_F1_IS_ENABLE:
|
||||
if(hw->CON1&BIT(1)){
|
||||
ret_val = 1;
|
||||
}else{
|
||||
ret_val = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_F1_MODE:
|
||||
if(hw->CON1&BIT(17)){
|
||||
ret_val = 1; //2N mode
|
||||
}else{
|
||||
ret_val = 0; //16+2n mode
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_F1_SHRINK:
|
||||
ret_val = (hw->CON1&0x07)>>2;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SRAMBUFF_CNT_MODE:
|
||||
if(param1 == 1){ //VPP BUF0
|
||||
hw->CON1 |= BIT(16); //2N
|
||||
}else{
|
||||
hw->CON1 &= ~BIT(16); //16+2N
|
||||
}
|
||||
|
||||
if(param2 == 1){ //VPP BUF1
|
||||
hw->CON1 |= BIT(17); //2N
|
||||
}else{
|
||||
hw->CON1 &= ~BIT(17); //16+2N
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SCALEBUF_SELECT:
|
||||
if(param1 == 1){ //SCALE1
|
||||
hw->CON1 |= BIT(18); //BUF 1
|
||||
}else{
|
||||
hw->CON1 &= ~BIT(18); //BUF 0
|
||||
}
|
||||
|
||||
if(param2 == 1){ //SCALE3
|
||||
hw->CON1 |= BIT(19); //BUF 1
|
||||
}else{
|
||||
hw->CON1 &= ~BIT(19); //BUF 0
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_SCALE1BUF_SELECT:
|
||||
if(hw->CON1&BIT(18)){
|
||||
ret_val = 1; //<2F>õ<EFBFBD><C3B5><EFBFBD>buf1
|
||||
}else{
|
||||
ret_val = 0; //<2F>õ<EFBFBD><C3B5><EFBFBD>buf0
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GET_SCALE3BUF_SELECT:
|
||||
if(hw->CON1&BIT(19)){
|
||||
ret_val = 1; //<2F>õ<EFBFBD><C3B5><EFBFBD>buf1
|
||||
}else{
|
||||
ret_val = 0; //<2F>õ<EFBFBD><C3B5><EFBFBD>buf0
|
||||
}
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_GEN420_BUF_SEL:
|
||||
if(param1 == 0){
|
||||
hw->CON1 &= ~BIT(20); //BUF 0
|
||||
}else{
|
||||
hw->CON1 |= BIT(20); //BUF 1
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_AUTO_RC_THRESHOLD:
|
||||
hw->IWM0_CON1 = 0;
|
||||
hw->IWM0_CON1 = param1/8;
|
||||
hw->IWM0_CON1 |= (param2/8)<<18;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_AUTO_RC_COLOR:
|
||||
if(param1)
|
||||
hw->IWM0_CON |= BIT(6);
|
||||
else
|
||||
hw->IWM0_CON &= ~BIT(6);
|
||||
|
||||
hw->IWM0_YUV1 = param2;
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_AUTO_RC_HADR:
|
||||
hw->IWM0_HADR = param1; //sram for moudle cal threshold
|
||||
break;
|
||||
|
||||
case VPP_IOCTL_CMD_SET_WATERMARK0_AUTO_RC_MODE:
|
||||
if(param1)
|
||||
hw->IWM0_CON |= BIT(7);
|
||||
else
|
||||
hw->IWM0_CON &= ~BIT(7);
|
||||
|
||||
break;
|
||||
case VPP_IOCTL_CMD_IS_CLOSED:
|
||||
ret_val = vpp_hw->opened?0:1;
|
||||
break;
|
||||
default:
|
||||
os_printf("NO VPP IOCTL:%d\r\n",ioctl_cmd);
|
||||
ret_val = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void VPP_IRQHandler_action(void *p_vpp)
|
||||
{
|
||||
uint32 jpgr = 0;
|
||||
uint32 sta = 0;
|
||||
uint8 loop;
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
jpgr = *(volatile uint32_t*)0x40005200; //fix jpg reg error bug,imp
|
||||
sta = hw->STA;
|
||||
for(loop = 0;loop < VPP_IRQ_NUM;loop++){
|
||||
if(sta&BIT(loop)){
|
||||
hw->STA = BIT(loop);
|
||||
if(loop == IPF_OV_ISR){
|
||||
isp_ov_err = 1;
|
||||
}
|
||||
|
||||
if(isp_ov_err){
|
||||
if(loop == FRAME_DONE_ISR){
|
||||
os_printf("isp ov,vpp drop\r\n");
|
||||
isp_ov_err = 0;
|
||||
}
|
||||
}else{
|
||||
if(loop == FRAME_DONE_ISR){
|
||||
isp_ov_err = 0;
|
||||
}
|
||||
|
||||
if(vppirq_vector_table[loop] != NULL)
|
||||
vppirq_vector_table[loop] (loop,vppirq_dev_table[loop],0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void irq_vpp_enable(struct vpp_device *p_vpp,uint8 mode,uint8 irq){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
if(mode){
|
||||
hw->CON |= BIT(irq+19);
|
||||
}else{
|
||||
hw->CON &= ~BIT(irq+19);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32 vppirq_register(struct vpp_device *p_vpp,uint32 irq, vpp_irq_hdl isr, uint32 dev_id){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
request_irq(vpp_hw->irq_num, VPP_IRQHandler_action, p_vpp);
|
||||
|
||||
irq_vpp_enable(p_vpp, 1, irq);
|
||||
vppirq_vector_table[irq] = isr;
|
||||
vppirq_dev_table[irq] = dev_id;
|
||||
hw->STA |= BIT(irq);
|
||||
os_printf("vppirq_register:%d %x %x\r\n",irq,(uint32)vppirq_vector_table[irq],(uint32)isr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 vppirq_unregister(struct vpp_device *p_vpp,uint32 irq){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
irq_vpp_enable(p_vpp, 0, irq);
|
||||
vppirq_vector_table[irq] = NULL;
|
||||
vppirq_dev_table[irq] = 0;
|
||||
hw->STA |= BIT(irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int32 hgvpp_open(struct vpp_device *p_vpp){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
vpp_hw->opened = 1;
|
||||
hw->CON |= BIT(0);
|
||||
irq_enable(vpp_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 hgvpp_close(struct vpp_device *p_vpp){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)p_vpp;
|
||||
struct hgvpp_hw *hw = (struct hgvpp_hw *)vpp_hw->hw;
|
||||
vpp_hw->opened = 0;
|
||||
hw->CON &= ~BIT(0);
|
||||
irq_disable(vpp_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 hgvpp_suspend(struct dev_obj *obj){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)obj;
|
||||
struct hgvpp_hw *hw;
|
||||
struct hgvpp_hw *hw_cfg;
|
||||
//确保已经被打开并且休眠过,直接返回
|
||||
if(!vpp_hw->opened || vpp_hw->dsleep)
|
||||
{
|
||||
return RET_OK;
|
||||
}
|
||||
vpp_hw->dsleep = 1;
|
||||
vpp_hw->cfg_backup = (uint32 *)os_malloc(sizeof(struct hgvpp_hw));
|
||||
hw_cfg = (struct hgvpp_hw*)vpp_hw->cfg_backup;
|
||||
hw = (struct hgvpp_hw*)vpp_hw->hw;
|
||||
|
||||
hw_cfg->CON = hw->CON;
|
||||
hw_cfg->CON1 = hw->CON1;
|
||||
hw_cfg->SIZE = hw->SIZE;
|
||||
hw_cfg->DLT = hw->DLT;
|
||||
hw_cfg->DHT = hw->DHT;
|
||||
hw_cfg->STA = hw->STA;
|
||||
hw_cfg->DMA_YADR = hw->DMA_YADR;
|
||||
hw_cfg->DMA_UADR = hw->DMA_UADR;
|
||||
hw_cfg->DMA_VADR = hw->DMA_VADR;
|
||||
hw_cfg->DMA_YADR1 = hw->DMA_YADR1;
|
||||
hw_cfg->DMA_UADR1 = hw->DMA_UADR1;
|
||||
hw_cfg->DMA_VADR1 = hw->DMA_VADR1;
|
||||
hw_cfg->IWM0_CON = hw->IWM0_CON;
|
||||
hw_cfg->IWM0_CON1 = hw->IWM0_CON1;
|
||||
hw_cfg->IWM0_SIZE = hw->IWM0_SIZE;
|
||||
hw_cfg->IWM0_YUV = hw->IWM0_YUV;
|
||||
hw_cfg->IWM0_YUV1 = hw->IWM0_YUV1;
|
||||
hw_cfg->IWM0_LADR = hw->IWM0_LADR;
|
||||
hw_cfg->IWM0_HADR = hw->IWM0_HADR;
|
||||
hw_cfg->IWM0_IDX0 = hw->IWM0_IDX0;
|
||||
hw_cfg->IWM0_IDX1 = hw->IWM0_IDX1;
|
||||
hw_cfg->IWM0_IDX2 = hw->IWM0_IDX2;
|
||||
hw_cfg->IWM1_CON = hw->IWM1_CON;
|
||||
hw_cfg->IWM1_SIZE = hw->IWM1_SIZE;
|
||||
hw_cfg->IWM1_YUV = hw->IWM1_YUV;
|
||||
hw_cfg->IWM1_LADR = hw->IWM1_LADR;
|
||||
hw_cfg->IPF_SADR = hw->IPF_SADR;
|
||||
hw_cfg->MD_CON = hw->MD_CON;
|
||||
hw_cfg->MD_WIN_CON0 = hw->MD_WIN_CON0;
|
||||
hw_cfg->MD_WIN_CON1 = hw->MD_WIN_CON1;
|
||||
hw_cfg->MD_BASE_ADDR = hw->MD_BASE_ADDR;
|
||||
hw_cfg->ITP_PSRAM_YADR = hw->ITP_PSRAM_YADR;
|
||||
hw_cfg->ITP_PSRAM_UADR = hw->ITP_PSRAM_UADR;
|
||||
hw_cfg->ITP_PSRAM_VADR = hw->ITP_PSRAM_VADR;
|
||||
hw_cfg->FRM_PSRAM_YCNT = hw->FRM_PSRAM_YCNT;
|
||||
hw_cfg->FRM_PSRAM_UVCNT = hw->FRM_PSRAM_UVCNT;
|
||||
hw_cfg->FRM1_PSRAM_YCNT = hw->FRM1_PSRAM_YCNT;
|
||||
hw_cfg->FRM1_PSRAM_UVCNT = hw->FRM1_PSRAM_UVCNT;
|
||||
|
||||
|
||||
irq_disable(vpp_hw->irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 hgvpp_resume(struct dev_obj *obj){
|
||||
struct hgvpp *vpp_hw = (struct hgvpp*)obj;
|
||||
struct hgvpp_hw *hw;
|
||||
struct hgvpp_hw *hw_cfg;
|
||||
//如果已经被打开并且没有休眠过,直接返回
|
||||
if(!vpp_hw->opened || !vpp_hw->dsleep)
|
||||
{
|
||||
return RET_OK;
|
||||
}
|
||||
vpp_hw->dsleep = 0;
|
||||
hw_cfg = (struct hgvpp_hw*)vpp_hw->cfg_backup;
|
||||
hw = (struct hgvpp_hw*)vpp_hw->hw;
|
||||
hw->CON = hw_cfg->CON;
|
||||
hw->CON1 = hw_cfg->CON1;
|
||||
hw->SIZE = hw_cfg->SIZE;
|
||||
hw->DLT = hw_cfg->DLT;
|
||||
hw->DHT = hw_cfg->DHT;
|
||||
hw->STA = hw_cfg->STA;
|
||||
hw->DMA_YADR = hw_cfg->DMA_YADR;
|
||||
hw->DMA_UADR = hw_cfg->DMA_UADR;
|
||||
hw->DMA_VADR = hw_cfg->DMA_VADR;
|
||||
hw->DMA_YADR1 = hw_cfg->DMA_YADR1;
|
||||
hw->DMA_UADR1 = hw_cfg->DMA_UADR1;
|
||||
hw->DMA_VADR1 = hw_cfg->DMA_VADR1;
|
||||
hw->IWM0_CON = hw_cfg->IWM0_CON;
|
||||
hw->IWM0_CON1 = hw_cfg->IWM0_CON1;
|
||||
hw->IWM0_SIZE = hw_cfg->IWM0_SIZE;
|
||||
hw->IWM0_YUV = hw_cfg->IWM0_YUV;
|
||||
hw->IWM0_YUV1 = hw_cfg->IWM0_YUV1;
|
||||
hw->IWM0_LADR = hw_cfg->IWM0_LADR;
|
||||
hw->IWM0_HADR = hw_cfg->IWM0_HADR;
|
||||
hw->IWM0_IDX0 = hw_cfg->IWM0_IDX0;
|
||||
hw->IWM0_IDX1 = hw_cfg->IWM0_IDX1;
|
||||
hw->IWM0_IDX2 = hw_cfg->IWM0_IDX2;
|
||||
hw->IWM1_CON = hw_cfg->IWM1_CON;
|
||||
hw->IWM1_SIZE = hw_cfg->IWM1_SIZE;
|
||||
hw->IWM1_YUV = hw_cfg->IWM1_YUV;
|
||||
hw->IWM1_LADR = hw_cfg->IWM1_LADR;
|
||||
hw->IPF_SADR = hw_cfg->IPF_SADR;
|
||||
hw->MD_CON = hw_cfg->MD_CON;
|
||||
hw->MD_WIN_CON0 = hw_cfg->MD_WIN_CON0;
|
||||
hw->MD_WIN_CON1 = hw_cfg->MD_WIN_CON1;
|
||||
hw->MD_BASE_ADDR = hw_cfg->MD_BASE_ADDR;
|
||||
hw->ITP_PSRAM_YADR = hw_cfg->ITP_PSRAM_YADR;
|
||||
hw->ITP_PSRAM_UADR = hw_cfg->ITP_PSRAM_UADR;
|
||||
hw->ITP_PSRAM_VADR = hw_cfg->ITP_PSRAM_VADR;
|
||||
hw->FRM_PSRAM_YCNT = hw_cfg->FRM_PSRAM_YCNT;
|
||||
hw->FRM_PSRAM_UVCNT = hw_cfg->FRM_PSRAM_UVCNT;
|
||||
hw->FRM1_PSRAM_YCNT = hw_cfg->FRM1_PSRAM_YCNT;
|
||||
hw->FRM1_PSRAM_UVCNT = hw_cfg->FRM1_PSRAM_UVCNT;
|
||||
irq_enable(vpp_hw->irq_num);
|
||||
os_free(vpp_hw->cfg_backup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct vpp_hal_ops dev_ops = {
|
||||
.open = hgvpp_open,
|
||||
.close = hgvpp_close,
|
||||
.ioctl = hgvpp_ioctl,
|
||||
.request_irq = vppirq_register,
|
||||
.release_irq = vppirq_unregister,
|
||||
#ifdef CONFIG_SLEEP
|
||||
.ops.suspend = hgvpp_suspend,
|
||||
.ops.resume = hgvpp_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
int32 hgvpp_attach(uint32 dev_id, struct hgvpp *vpp){
|
||||
vpp->opened = 0;
|
||||
vpp->use_dma = 0;
|
||||
vpp->irq_hdl = NULL;
|
||||
//memset(dvp->irq_hdl,0,sizeof(dvp->irq_hdl));
|
||||
vpp->irq_data = 0;
|
||||
//memset(dvp->irq_data,0,sizeof(dvp->irq_data));
|
||||
vpp->dev.dev.ops = (const struct devobj_ops *)&dev_ops;
|
||||
|
||||
irq_disable(vpp->irq_num);
|
||||
dev_register(dev_id, (struct dev_obj *)vpp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user