hpw422初始版本
This commit is contained in:
@@ -0,0 +1,662 @@
|
||||
/*!
|
||||
* \file xc6xxx_hal_spi.c
|
||||
*
|
||||
* \brief Target xc6xxx hal spi implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "xc6xxx.h"
|
||||
#include "xc_drv_fmc_spi.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool SPI_DMA_IT_Enable_Flag[3];
|
||||
uint8_t SPI_Mode[3];
|
||||
} SPI_CtrlBlock_Typedef;
|
||||
|
||||
SPI_CtrlBlock_Typedef m_spi_cb;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Func Prototype
|
||||
-------------------------------------------------------------------------------------*/
|
||||
eXC_RESULT xc_spi_write_bytes(uint8_t reg_idx, uint8_t *txdata, uint16_t len);
|
||||
eXC_RESULT xc_spi_read_bytes(uint8_t reg_idx, uint8_t *rxdata, uint16_t len);
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void xc_spi_init(uint8_t reg_idx, SPI_InitCfg_t *init_cfg)
|
||||
{
|
||||
#if (USE_XIP == 0)
|
||||
if (SPI0_IDX == reg_idx) {
|
||||
cpr_rstctl_subrst_sw__ssi0_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__ssi0_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_ctlapbclken_grctl__ssi0_pclk_en__setf(ENABLE);
|
||||
|
||||
cpr_ssi0_mclk_ctl__ssi_mclk_div__setf(0);
|
||||
cpr_ssi0_mclk_ctl__ssi_mclk_en__setf(1);
|
||||
|
||||
cpr_ssi_ctrl__ssi0_protocol__setf(SSI_CTRL0_FRF_MOTOROLA);
|
||||
|
||||
}
|
||||
#endif
|
||||
if (SPI1_IDX == reg_idx) {
|
||||
|
||||
cpr_rstctl_subrst_sw__ssi1_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__ssi1_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_ssi1_mclk_ctl__ssi_mclk_div__setf(0);
|
||||
cpr_ssi1_mclk_ctl__ssi_mclk_en__setf(1);
|
||||
|
||||
cpr_ctlapbclken_grctl__ssi1_pclk_en__setf(ENABLE);
|
||||
|
||||
if (init_cfg->Mode == SPI_MODE_MASTER) {
|
||||
|
||||
cpr_ssi_ctrl__ssi1_master_en__setf(ENABLE);
|
||||
} else if (init_cfg->Mode == SPI_MODE_SLAVE) {
|
||||
|
||||
cpr_ssi_ctrl__ssi1_master_en__setf(DISABLE);
|
||||
}
|
||||
cpr_ssi_ctrl__ssi1_protocol__setf(SSI_CTRL0_FRF_MOTOROLA);
|
||||
} else if (SPI2_IDX == reg_idx) {
|
||||
|
||||
cpr_rstctl_subrst_sw__ssi2_rstn__setf(RSTCTL_ENABLE);
|
||||
cpr_rstctl_subrst_sw__ssi2_rstn__setf(RSTCTL_DISABLE);
|
||||
|
||||
cpr_ssi1_mclk_ctl__ssi2_mclk_div__setf(0);
|
||||
cpr_ssi1_mclk_ctl__ssi2_mclk_en__setf(1);
|
||||
|
||||
cpr_ctlapbclken_grctl__ssi2_pclk_en__setf(ENABLE);
|
||||
|
||||
cpr_ssi_ctrl__ssi2_protocol__setf(SSI_CTRL0_FRF_MOTOROLA);
|
||||
}
|
||||
|
||||
spi_en_set(reg_idx, DISABLE);
|
||||
// sste is automatically set to 1 when spi slave is initialized.
|
||||
// therefor, manually clear this bit to 0 here.
|
||||
spi_ctrl0__ssi_sste__setf(reg_idx, DISABLE);
|
||||
spi_ctrl0__ssi_tmod__setf(reg_idx, init_cfg->Direction);
|
||||
spi_ctrl0__ssi_scpol__setf(reg_idx, init_cfg->CLKPolarity);
|
||||
spi_ctrl0__ssi_scpha__setf(reg_idx, init_cfg->CLKPhase);
|
||||
spi_ctrl0__ssi_dfs__setf(reg_idx, init_cfg->DataSize);
|
||||
|
||||
spi_ie_set(reg_idx, DISABLE);
|
||||
spi_se_set(reg_idx, ENABLE);
|
||||
spi_baud__ssi_sckdv__setf(reg_idx, init_cfg->BaudRatePrescaler);
|
||||
spi_txftl__ssi_tft__setf(reg_idx, SSI_TXFTL_FIFO_1);
|
||||
spi_rxftl__ssi_rft__setf(reg_idx, SSI_RXFTL_FIFO_1);
|
||||
}
|
||||
|
||||
static void xc_spi_enable(uint8_t reg_idx, uint8_t dfs)
|
||||
{
|
||||
spi_en__ssi_sen__setf(reg_idx, DISABLE);
|
||||
spi_dmas_set(reg_idx, DISABLE);
|
||||
spi_ctrl0__ssi_dfs__setf(reg_idx, dfs);
|
||||
spi_en__ssi_sen__setf(reg_idx, ENABLE);
|
||||
}
|
||||
|
||||
static void xc_spi_disable(uint8_t reg_idx) { spi_en__ssi_sen__setf(reg_idx, DISABLE); }
|
||||
|
||||
void xc_spi_rxftl_fifo_set(uint8_t reg_idx, uint8_t val)
|
||||
{
|
||||
spi_rxftl__ssi_rft__setf(reg_idx, val);
|
||||
}
|
||||
|
||||
void xc_spi_txftl_fifo_set(uint8_t reg_idx, uint8_t val)
|
||||
{
|
||||
spi_txftl__ssi_tft__setf(reg_idx, val);
|
||||
}
|
||||
|
||||
void xc_spi_enable_it(uint8_t reg_idx, uint8_t val) { spi_ie_set(reg_idx, val); }
|
||||
|
||||
void xc_spi_disable_it(uint8_t reg_idx, uint8_t val) { spi_ie_set(reg_idx, val); }
|
||||
|
||||
void xc_spi_flash_power_down(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t txbuff[2] = {0};
|
||||
|
||||
txbuff[1] = CMD_PWRDWN;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_8BIT);
|
||||
xc_spi_write_bytes(reg_idx, txbuff, sizeof(txbuff));
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
void xc_spi_flash_wake_up(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t txbuff[2] = {0};
|
||||
|
||||
txbuff[1] = CMD_RELEASE_PWRDWN;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_8BIT);
|
||||
xc_spi_write_bytes(reg_idx, txbuff, sizeof(txbuff));
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
static uint8_t xc_spi_flash_wait_busy(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t cmd[2] = {0};
|
||||
uint8_t sta[2] = {0xff, 0xff};
|
||||
|
||||
cmd[0] = CMD_READ_STATUS;
|
||||
cmd[1] = 0xff;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
xc_spi_read_bytes(reg_idx, sta, sizeof(sta));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
return (sta[1] & 0x01);
|
||||
}
|
||||
|
||||
static void xc_spi_flash_write_enable(uint8_t reg_idx)
|
||||
{
|
||||
uint8_t txbuff[2] = {0};
|
||||
|
||||
txbuff[1] = CMD_WRITE_ENABLE;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_8BIT);
|
||||
xc_spi_write_bytes(reg_idx, txbuff, sizeof(txbuff));
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
eXC_RESULT xc_spi_flash_erase_sector(uint8_t reg_idx, uint32_t Dst_Addr)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_flash_write_enable(reg_idx);
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
cmd[0] = CMD_SECTOR_ERASE;
|
||||
cmd[1] = Dst_Addr >> 16;
|
||||
cmd[2] = Dst_Addr >> 8;
|
||||
cmd[3] = Dst_Addr;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
#if (USE_INTEGRATED_FlASH == USE_PUYA_FlASH)
|
||||
void xc_spi_flash_erase_page(uint8_t reg_idx, uint32_t Dst_Addr)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_flash_write_enable(reg_idx);
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
cmd[0] = CMD_PAGE_ERASE;
|
||||
cmd[1] = Dst_Addr >> 16;
|
||||
cmd[2] = Dst_Addr >> 8;
|
||||
cmd[3] = Dst_Addr;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
void xc_spi_flash_write_page(uint8_t reg_idx, uint32_t WriteAddr, uint8_t *pBuffer)
|
||||
{
|
||||
uint32_t addr = WriteAddr;
|
||||
uint8_t cmd[16 + 4] = {0};
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_flash_write_enable(reg_idx);
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
|
||||
cmd[0] = CMD_PAGE_PROGRAM;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
memcpy(&cmd[4], pBuffer + i * 16, 16);
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
addr += 16;
|
||||
}
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
void xc_spi_flash_read_page(uint8_t reg_idx, uint32_t ReadAddr, uint8_t *pBuffer)
|
||||
{
|
||||
uint8_t cmd[16 + 4] = {0};
|
||||
uint8_t mid[16 + 4] = {0};
|
||||
uint16_t rx_idx = 0;
|
||||
uint32_t addr = ReadAddr;
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
cmd[0] = CMD_READ_DATA;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
xc_spi_read_bytes(reg_idx, mid, sizeof(cmd));
|
||||
|
||||
memcpy(&pBuffer[rx_idx], mid + 4, 16);
|
||||
addr += 16;
|
||||
rx_idx += 16;
|
||||
}
|
||||
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_flash_write(uint8_t reg_idx, uint32_t writeAddr, uint8_t *buff,
|
||||
uint16_t size)
|
||||
{
|
||||
uint32_t cur_addr = writeAddr;
|
||||
uint32_t end_addr = writeAddr + size;
|
||||
uint16_t wt_len = 0;
|
||||
// The current page number occupied by this data storage
|
||||
uint16_t CurSectorNum = 0;
|
||||
uint16_t CurPageNum = 0;
|
||||
// The position occupied by this address on the current page
|
||||
uint32_t CurStartPsr = 0;
|
||||
|
||||
uint32_t mid = 0;
|
||||
xc_spi_flash_rdid(reg_idx ,(uint8_t*)&mid);
|
||||
|
||||
if(mid != GD_FlASH_RDID){
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE];
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
CurPageNum = CUR_PAGE_NUM(cur_addr);
|
||||
CurStartPsr = CUR_START_PSR(cur_addr);
|
||||
|
||||
xc_spi_flash_read_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE, temp_buff);
|
||||
|
||||
xc_spi_flash_erase_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE);
|
||||
|
||||
if (CurStartPsr) {
|
||||
memcpy(&temp_buff[CurStartPsr], buff + wt_len,
|
||||
(FLASH_PAGE_SIZE - CurStartPsr) > size - wt_len // 当前扇区剩余的空间是否满足写长度
|
||||
? size - wt_len
|
||||
: (FLASH_PAGE_SIZE - CurStartPsr));
|
||||
wt_len += wt_len + ((FLASH_PAGE_SIZE - CurStartPsr) > size - wt_len
|
||||
? size - wt_len
|
||||
: (FLASH_PAGE_SIZE - CurStartPsr));
|
||||
cur_addr += wt_len;
|
||||
} else {
|
||||
memcpy(temp_buff, buff + wt_len,
|
||||
size - wt_len > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE
|
||||
: size - wt_len);
|
||||
cur_addr += (size - wt_len > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE
|
||||
: size - wt_len);
|
||||
wt_len += (size - wt_len > FLASH_PAGE_SIZE ? FLASH_PAGE_SIZE
|
||||
: size - wt_len);
|
||||
}
|
||||
|
||||
xc_spi_flash_write_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE, temp_buff);
|
||||
}
|
||||
|
||||
}else if(mid == GD_FlASH_RDID){
|
||||
uint8_t temp_buff[FLASH_SECTOR_SIZE];
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
CurSectorNum = CUR_SECTOR_NUM(cur_addr);
|
||||
CurStartPsr = CUR_START_PSR(cur_addr);
|
||||
for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
|
||||
xc_spi_flash_read_page(reg_idx, CurSectorNum * FLASH_SECTOR_SIZE + i* FLASH_PAGE_SIZE, temp_buff+i*FLASH_PAGE_SIZE);
|
||||
}
|
||||
|
||||
xc_spi_flash_erase_sector(reg_idx ,CurSectorNum * FLASH_SECTOR_SIZE);
|
||||
|
||||
if (CurStartPsr) {
|
||||
memcpy(&temp_buff[CurStartPsr], buff + wt_len,
|
||||
(FLASH_SECTOR_SIZE - CurStartPsr) > size - wt_len // 当前扇区剩余的空间是否满足写长度
|
||||
? size - wt_len
|
||||
: (FLASH_SECTOR_SIZE - CurStartPsr));
|
||||
wt_len += wt_len + ((FLASH_SECTOR_SIZE - CurStartPsr) > size - wt_len
|
||||
? size - wt_len
|
||||
: (FLASH_SECTOR_SIZE - CurStartPsr));
|
||||
cur_addr += wt_len;
|
||||
} else {
|
||||
memcpy(temp_buff, buff + wt_len,
|
||||
size - wt_len > FLASH_SECTOR_SIZE ? FLASH_SECTOR_SIZE
|
||||
: size - wt_len);
|
||||
cur_addr += (size - wt_len > FLASH_SECTOR_SIZE ? FLASH_SECTOR_SIZE
|
||||
: size - wt_len);
|
||||
wt_len += (size - wt_len > FLASH_SECTOR_SIZE ? FLASH_SECTOR_SIZE
|
||||
: size - wt_len);
|
||||
}
|
||||
|
||||
for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
|
||||
xc_spi_flash_write_page(reg_idx, CurSectorNum * FLASH_SECTOR_SIZE + i* FLASH_PAGE_SIZE, temp_buff+i*FLASH_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_flash_read(uint8_t reg_idx, uint32_t readAddr, uint8_t *buff,
|
||||
uint16_t len)
|
||||
{
|
||||
eXC_RESULT ret = XR_OK;
|
||||
// The page number to be occupied by the data written this time
|
||||
uint16_t ReqPageCnt = 0;
|
||||
// The current page number occupied by this data storage
|
||||
uint16_t CurPageNum = 0;
|
||||
// The position occupied by this address on the current page
|
||||
uint16_t CurStartPsr = 0;
|
||||
// The next page number that may be occupied by this data storage
|
||||
uint16_t NextPageNum = 0;
|
||||
// The end address of the next page that may be occupied by this data
|
||||
// storage
|
||||
uint16_t NextStopPsr = 0;
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = {0};
|
||||
|
||||
if (len <= FLASH_PAGE_SIZE) {
|
||||
CurPageNum = CUR_PAGE_NUM(readAddr);
|
||||
CurStartPsr = CUR_START_PSR(readAddr);
|
||||
if ((len + CurStartPsr) > FLASH_PAGE_SIZE)
|
||||
ReqPageCnt = 2;
|
||||
else
|
||||
ReqPageCnt = 1;
|
||||
|
||||
if (ReqPageCnt == 1) // Note that only one page is read here
|
||||
{
|
||||
xc_spi_flash_read_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE,
|
||||
temp_buff);
|
||||
memcpy(buff, &temp_buff[CurStartPsr], len);
|
||||
} else if (ReqPageCnt == 2) {
|
||||
NextPageNum = CurPageNum + 1;
|
||||
NextStopPsr = len + CurStartPsr - FLASH_PAGE_SIZE;
|
||||
// First page read
|
||||
xc_spi_flash_read_page(reg_idx, CurPageNum * FLASH_PAGE_SIZE,
|
||||
temp_buff);
|
||||
memcpy(buff, &temp_buff[CurStartPsr], len - NextStopPsr);
|
||||
// second page read
|
||||
uint16_t HaveCopyNum = len - NextStopPsr;
|
||||
xc_spi_flash_read_page(reg_idx, NextPageNum * FLASH_PAGE_SIZE,
|
||||
temp_buff);
|
||||
memcpy(buff + HaveCopyNum, temp_buff, NextStopPsr);
|
||||
}
|
||||
} else {
|
||||
CurPageNum = CUR_PAGE_NUM(readAddr);
|
||||
CurStartPsr = CUR_START_PSR(readAddr);
|
||||
NextPageNum = CurPageNum + 1;
|
||||
|
||||
uint16_t buff_idx = 0;
|
||||
uint16_t pre_len = NextPageNum * FLASH_PAGE_SIZE - readAddr;
|
||||
uint32_t pre_addr = CurPageNum * FLASH_PAGE_SIZE;
|
||||
xc_spi_flash_read_page(reg_idx, pre_addr, temp_buff);
|
||||
memcpy(buff, &temp_buff[CurStartPsr], pre_len);
|
||||
buff_idx += pre_len;
|
||||
|
||||
pre_addr = NextPageNum * FLASH_PAGE_SIZE;
|
||||
while (buff_idx < len) {
|
||||
if ((len - buff_idx) >= FLASH_PAGE_SIZE) {
|
||||
xc_spi_flash_read_page(reg_idx, pre_addr, temp_buff);
|
||||
memcpy(&buff[buff_idx], temp_buff, FLASH_PAGE_SIZE);
|
||||
buff_idx += FLASH_PAGE_SIZE;
|
||||
pre_addr += FLASH_PAGE_SIZE;
|
||||
} else {
|
||||
xc_spi_flash_read_page(reg_idx, pre_addr, temp_buff);
|
||||
memcpy(&buff[buff_idx], temp_buff, len - buff_idx);
|
||||
buff_idx += (len - buff_idx);
|
||||
pre_addr += (len - buff_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void xc_spi_flash_read_128bit_uid(uint8_t reg_idx, uint8_t *buff)
|
||||
{
|
||||
while (xc_spi_flash_wait_busy(reg_idx)) {
|
||||
DEBUG("line=%d,status=%d\n", __LINE__, xc_spi_flash_wait_busy(reg_idx));
|
||||
};
|
||||
|
||||
uint8_t cmd[21] = {0};
|
||||
uint8_t id[21] = {0};
|
||||
|
||||
cmd[0] = CMD_RUID;
|
||||
cmd[1] = 0x00;
|
||||
cmd[2] = 0x00;
|
||||
cmd[3] = 0x00;
|
||||
cmd[4] = 0x00;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
xc_spi_read_bytes(reg_idx, id, sizeof(id));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
memcpy(buff, &id[5], 16);
|
||||
}
|
||||
|
||||
eXC_RESULT xc_spi_flash_rdid(uint8_t reg_idx, uint8_t *buff)
|
||||
{
|
||||
while (xc_spi_flash_wait_busy(reg_idx)) {
|
||||
DEBUG("line=%d,status=%d\n", __LINE__, xc_spi_flash_wait_busy(reg_idx));
|
||||
};
|
||||
|
||||
uint8_t cmd[4] = {0};
|
||||
uint8_t id[4] = {0};
|
||||
|
||||
cmd[0] = CMD_RDID;
|
||||
cmd[1] = 0xff;
|
||||
cmd[2] = 0xff;
|
||||
cmd[3] = 0xff;
|
||||
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
xc_spi_read_bytes(reg_idx, id, sizeof(id));
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
memcpy(buff, &id[1], 3);
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/*---------------------------------- SPI1 Master & Slave API
|
||||
* ---------------------------------------*/
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only Master & Slave
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
static void xc_spi_datasize_set(uint8_t reg_idx, uint8_t dfs)
|
||||
{
|
||||
|
||||
spi_en_set(reg_idx, DISABLE);
|
||||
spi_ctrl0__ssi_dfs__setf(reg_idx, dfs);
|
||||
spi_en_set(reg_idx, ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only applicable Master & Slave communication
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_write_bytes(uint8_t reg_idx, uint8_t *txdata, uint16_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return XR_ERROR;
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 2;
|
||||
uint16_t cnt = len / 2;
|
||||
uint16_t mid_data[128 + 1] = {0};
|
||||
uint16_t i = 0;
|
||||
|
||||
while (spi_sts__ssi_tfe__getf(reg_idx) == RESET) {
|
||||
i++;
|
||||
if (i >= SPI_WAIT_TIMEOUT) {
|
||||
|
||||
//h
|
||||
// DEBUG("func=%s,line=%d,timeout\n", __func__, __LINE__);
|
||||
return XR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt != 0) {
|
||||
for (n = 0; n < cnt; n++) {
|
||||
mid_data[n] = ((txdata[n * 2] << 8) | txdata[n * 2 + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (remain != 0) {
|
||||
for (n = 0; n < remain; n++) {
|
||||
mid_data[cnt] |= (txdata[cnt * 2 + n] << (16 - 8 * n));
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt != 0) {
|
||||
if (remain != 0)
|
||||
cnt = cnt + 1;
|
||||
for (n = 0; n < cnt; n++)
|
||||
spi_data_set(reg_idx, mid_data[n]);
|
||||
} else {
|
||||
spi_data_set(reg_idx, mid_data[0]);
|
||||
}
|
||||
|
||||
while ((spi_sts__ssi_rfne__getf(reg_idx) == RESET) ||
|
||||
(spi_sts__ssi_tfe__getf(reg_idx) == RESET)) {
|
||||
i++;
|
||||
if (i >= SPI_WAIT_TIMEOUT) {
|
||||
// DEBUG("func=%s,line=%d,timeout\n", __func__, __LINE__);
|
||||
return XR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only applicable Master & Slave communication
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_read_bytes(uint8_t reg_idx, uint8_t *rxdata, uint16_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return XR_ERROR;
|
||||
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 2;
|
||||
uint16_t cnt = len / 2;
|
||||
uint16_t mid_data = 0;
|
||||
|
||||
if (cnt != 0) {
|
||||
for (n = 0; n < cnt; n++) {
|
||||
|
||||
mid_data = spi_data_get(reg_idx);
|
||||
rxdata[n * 2] = mid_data >> 8;
|
||||
rxdata[n * 2 + 1] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
if (remain != 0) {
|
||||
|
||||
mid_data = spi_data_get(reg_idx);
|
||||
for (n = 0; n < remain; n++) {
|
||||
rxdata[cnt * 2 + n] = mid_data >> 8;
|
||||
rxdata[cnt * 2 + 1 + n] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
return XR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief Only applicable Master & Slave communication
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
void xc_spi_write_and_read_data(uint8_t reg_idx, uint8_t *w_data, uint16_t w_size,
|
||||
uint8_t *r_data, uint16_t r_size)
|
||||
{
|
||||
if (w_size != (spi_rxftl_get(reg_idx) + 1) * 2)
|
||||
return;
|
||||
xc_spi_datasize_set(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
xc_spi_write_bytes(reg_idx, w_data, w_size);
|
||||
|
||||
while (!(spi_is_get(reg_idx) == SSI_IS_RXFIS_SET))
|
||||
;
|
||||
xc_spi_read_bytes(reg_idx, r_data, r_size);
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
Reference in New Issue
Block a user