初始提交

This commit is contained in:
2024-09-28 14:24:04 +08:00
commit c756587541
5564 changed files with 2413077 additions and 0 deletions

252
driver/src/hw3/smc.c Normal file
View File

@@ -0,0 +1,252 @@
/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "hw_reg_api.h"
#include "smc_rf.h"
#include "smc_rf_s.h"
#include "smc.h"
/* SFC and SMC share the same buffer, but they cannot be used at the same time */
#define SMC_BUFFER_ADDR SFC_MEM_BASEADDR
/* smc transmit ena */
smc_sts_type_t hal_smc_qspi_start()
{
uint32_t tmp;
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_ENA, tmp, 1);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
return SMC_QSPI_ERROR;
}
smc_sts_type_t hal_smc_disable()
{
uint32_t tmp;
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_ENA, tmp, 0);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
tmp = SMC_READ_REG(CFG_SMC_CLK0_ADDR);
REG_FIELD_SET(CLK_SPI_SMC_ENA, tmp, 0);
SMC_WRITE_REG((CFG_SMC_CLK0_ADDR), tmp);
return SMC_QSPI_OK;
}
/* smc quad cfg */
smc_sts_type_t hal_smc_qspi_quad_cfg(uint8_t clk)
{
uint32_t tmp;
/* quad read mode, quad write mode, little endian, spi is quad mode */
tmp = SMC_READ_REG(CFG_SMC_CFG0_ADDR);
REG_FIELD_SET(SMC_CACHE_RD_MODE, tmp, 2);
REG_FIELD_SET(SMC_CACHE_WR_MODE, tmp, 1);
REG_FIELD_SET(SMC_DATA_LE, tmp, 1);
REG_FIELD_SET(SMC_SPI_QPI_MODE, tmp, 1);
REG_FIELD_SET(SOFT_SMC_MODE, tmp, 0);
SMC_WRITE_REG(CFG_SMC_CFG0_ADDR, tmp);
tmp = SMC_READ_REG(CFG_SMC_CACHE_WCFG0_ADDR);
REG_FIELD_SET(CACHE_WR_DATA_QUAD_MODE, tmp, 1);
REG_FIELD_SET(CACHE_WR_ADDR_QUAD_MODE, tmp, 1);
SMC_WRITE_REG(CFG_SMC_CACHE_WCFG0_ADDR, tmp);
#if HW_PLATFORM == HW_PLATFORM_SILICON
tmp = SMC_READ_REG(CFG_SMC_CLK0_ADDR);
REG_FIELD_SET(CLK_SPI_SMC_ENA, tmp, 1);
REG_FIELD_SET(CLK_SPI_SMC_DIV, tmp, 0);
SMC_WRITE_REG(CFG_SMC_CLK0_ADDR, tmp);
#endif
return SMC_QSPI_OK;
}
bool_t is_smc_cmd_busy()
{
return REG_FIELD_GET(SW_SMC_ENA, SMC_READ_REG(CFG_SMC_CMD0_ADDR));
}
/* smc rst en */
smc_sts_type_t hal_smc_qspi_rst_en()
{
return SMC_QSPI_OK;
}
/* smc rst en */
smc_sts_type_t hal_smc_qspi_rst()
{
return SMC_QSPI_OK;
}
/* si:command + address */
smc_sts_type_t hal_smc_qspi_command(smc_op_t *cmd, uint32_t timeout)
{
uint32_t tmp;
/* cmd and addr */
tmp = SMC_READ_REG(CFG_SMC_CMD1_ADDR);
REG_FIELD_SET(SW_SMC_CMD, tmp, cmd->cmd);
REG_FIELD_SET(SW_SMC_ADDR, tmp, cmd->addr);
SMC_WRITE_REG(CFG_SMC_CMD1_ADDR, tmp);
/* operation and size */
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_MODE, tmp, cmd->smc_mode);
REG_FIELD_SET(SW_SMC_DLEN, tmp, cmd->smc_dlen);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
/* qpi mode */
tmp = SMC_READ_REG(CFG_SMC_CFG0_ADDR);
REG_FIELD_SET(SMC_SPI_QPI_MODE, tmp, cmd->qpi_mode);
SMC_WRITE_REG(CFG_SMC_CFG0_ADDR, tmp);
return SMC_QSPI_OK;
}
/* spi output:data */
smc_sts_type_t hal_smc_qspi_transmit(uint8_t *data, uint32_t len,
uint8_t is_buf, uint32_t timeout)
{
uint8_t *smc_data_buf;
(void)timeout;
if (is_buf) {
while(is_smc_cmd_busy());
smc_data_buf = (uint8_t *)(SMC_BUFFER_ADDR);
/* write data to buf ram */
while(len--)
{
*smc_data_buf = *data;
data++;
smc_data_buf++;
}
hal_smc_qspi_start();
} else {
#if 0 // Hardware not supported
uint32_t tmp;
uint32_t i, temp_addr, temp_len;
temp_addr = REG_FIELD_GET(SW_SMC_ADDR, SMC_READ_REG(CFG_SMC_CMD1_ADDR));
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_MODE, tmp, MOD_SMC_OP_REG_WR);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
for (i = 0; i < len; i += 4) {
while(is_smc_cmd_busy());
temp_len = (len - i >= 4) ? 4 : (len - i);
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_DLEN, tmp, temp_len);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
tmp = SMC_READ_REG(CFG_SMC_CMD1_ADDR);
REG_FIELD_SET(SW_SMC_ADDR, tmp, temp_addr);
SMC_WRITE_REG(CFG_SMC_CMD1_ADDR, tmp);
SMC_WRITE_REG(CFG_SMC_WDATA_ADDR, *((uint32_t *)data));
hal_smc_qspi_start();
temp_addr += 4;
data += 4;
}
#endif
}
return SMC_QSPI_OK;
}
/* spi input:data */
smc_sts_type_t hal_smc_qspi_receive(uint8_t *data, uint32_t len,
uint8_t is_buf, uint32_t timeout)
{
uint8_t *smc_data_buf;
if (is_buf) {
while(is_smc_cmd_busy());
smc_data_buf = (uint8_t *)(SMC_BUFFER_ADDR);
while(len--)
{
*data = *smc_data_buf;
data++;
smc_data_buf++;
}
} else {
#if 0 // Hardware not supported
uint32_t tmp, i, temp_addr, temp_len;
temp_addr = REG_FIELD_GET(SW_SMC_ADDR, SMC_READ_REG(CFG_SMC_CMD1_ADDR));
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_MODE, tmp, MOD_SMC_OP_REG_WR);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
for (i = 0; i < len; i += 4) {
while(is_smc_cmd_busy());
tmp = SMC_READ_REG(CFG_SMC_CMD0_ADDR);
REG_FIELD_SET(SW_SMC_DLEN, tmp, 4);
SMC_WRITE_REG(CFG_SMC_CMD0_ADDR, tmp);
tmp = SMC_READ_REG(CFG_SMC_CMD1_ADDR);
REG_FIELD_SET(SW_SMC_ADDR, tmp, temp_addr);
SMC_WRITE_REG(CFG_SMC_CMD1_ADDR, tmp);
/* start read to buf */
hal_smc_qspi_start();
tmp = SMC_READ_REG(CFG_SMC_WDATA_ADDR);
temp_len = (len - i >= 4) ? 4 : (len - i);
for (uint8_t j = 0; j < temp_len; j++) {
data[i + temp_len] = (tmp >> (j * 4)) & 0xff;
}
temp_addr += 4;
}
#endif
}
return SMC_QSPI_OK;
}
/* 0, 1(def), 2, 3 */
void IRAM_ATTR hal_smc_clk_div_set(uint8_t div)
{
uint32_t tmp;
tmp = SMC_READ_REG(CFG_SMC_CLK0_ADDR);
REG_FIELD_SET(CLK_SPI_SMC_DIV, tmp, div);
SMC_WRITE_REG(CFG_SMC_CLK0_ADDR, tmp);
}
void hal_smc_clk_out(int enable)
{
uint32_t tmp;
tmp = SMC_READ_REG(CFG_SMC_DBG0_ADDR);
if (enable) {
REG_FIELD_SET(SMC_CLK_FORCE_OUT, tmp, 1);
} else {
REG_FIELD_SET(SMC_CLK_FORCE_OUT, tmp, 0);
}
SMC_WRITE_REG(CFG_SMC_DBG0_ADDR, tmp);
}