初始提交
This commit is contained in:
252
driver/src/hw3/smc.c
Normal file
252
driver/src/hw3/smc.c
Normal 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user