hpw422移植新的sdk
This commit is contained in:
@@ -0,0 +1,673 @@
|
||||
/*!
|
||||
* \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"
|
||||
|
||||
#if XC_CHECK(XC_SPI_ENABLED)
|
||||
/*------------------------------------------------------------------------------------
|
||||
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);
|
||||
#ifndef FAST_SPI
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
#else
|
||||
xc_spi_write_2bytes(reg_idx, cmd, sizeof(cmd));
|
||||
#endif
|
||||
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);
|
||||
#ifndef FAST_SPI
|
||||
xc_spi_write_bytes(reg_idx, cmd, sizeof(cmd));
|
||||
#else
|
||||
xc_spi_write_2bytes(reg_idx, cmd, sizeof(cmd));
|
||||
#endif
|
||||
xc_spi_disable(reg_idx);
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
#ifndef FAST_SPI
|
||||
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);
|
||||
}
|
||||
#else
|
||||
void xc_spi_flash_write_page(uint8_t reg_idx, uint32_t WriteAddr, uint8_t *pBuffer)
|
||||
{
|
||||
|
||||
uint8_t cmd[256 + 4] = {0};
|
||||
|
||||
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] = WriteAddr >> 16;
|
||||
cmd[2] = WriteAddr >> 8;
|
||||
cmd[3] = WriteAddr;
|
||||
|
||||
memcpy(&cmd[4], pBuffer, FLASH_PAGE_SIZE);
|
||||
|
||||
xc_spi_write_2bytes(reg_idx, cmd, sizeof(cmd));
|
||||
|
||||
|
||||
while (xc_spi_flash_wait_busy(reg_idx))
|
||||
;
|
||||
xc_spi_disable(reg_idx);
|
||||
}
|
||||
#endif
|
||||
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 addr, uint8_t *buff,
|
||||
uint16_t size)
|
||||
{
|
||||
eXC_RESULT ret = XR_OK;
|
||||
uint32_t cur_addr = addr;
|
||||
uint32_t end_addr = addr + size;
|
||||
uint16_t wt_len = 0;
|
||||
// The current page number occupied by this data storage
|
||||
// The position occupied by this address on the current page
|
||||
uint32_t cur_start_psr = 0;
|
||||
uint16_t cur_size;
|
||||
|
||||
#ifndef GD_FlASH_INTEGRATION
|
||||
uint16_t cur_page_num = 0;
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE];
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
cur_page_num = CUR_PAGE_NUM(cur_addr);
|
||||
cur_start_psr = CUR_START_PSR(cur_addr);
|
||||
|
||||
xc_spi_flash_read_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE, temp_buff);
|
||||
xc_spi_flash_erase_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE);
|
||||
|
||||
if (cur_start_psr) {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE - cur_start_psr, size - wt_len);
|
||||
} else {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE, size - wt_len);
|
||||
}
|
||||
memcpy(&temp_buff[cur_start_psr], buff + wt_len, cur_size);
|
||||
wt_len += cur_size;
|
||||
cur_addr += cur_size;
|
||||
|
||||
xc_spi_flash_write_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE, temp_buff);
|
||||
}
|
||||
#else
|
||||
uint16_t cur_sector_num = 0;
|
||||
uint8_t temp_buff[FLASH_SECTOR_SIZE] = {0};
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
cur_sector_num = CUR_SECTOR_NUM(cur_addr);
|
||||
cur_start_psr = CUR_START_PSR(cur_addr);
|
||||
|
||||
for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
|
||||
xc_spi_flash_read_page(reg_idx, CUR_SECTOR_PAGE_ADDR(cur_sector_num, i), temp_buff+i*FLASH_PAGE_SIZE);
|
||||
}
|
||||
|
||||
xc_spi_flash_erase_sector(reg_idx, cur_sector_num * FLASH_SECTOR_SIZE);
|
||||
|
||||
if (cur_start_psr) {
|
||||
cur_size = MIN(FLASH_SECTOR_SIZE - cur_start_psr, size - wt_len);
|
||||
} else {
|
||||
cur_size = MIN(FLASH_SECTOR_SIZE, size - wt_len);
|
||||
}
|
||||
|
||||
memcpy(&temp_buff[cur_start_psr], buff + wt_len, cur_size);
|
||||
wt_len += cur_size;
|
||||
cur_addr += cur_size;
|
||||
|
||||
for(int i=0;i<FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE;i++){
|
||||
xc_spi_flash_write_page(reg_idx, CUR_SECTOR_PAGE_ADDR(cur_sector_num, i), temp_buff+i*FLASH_PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
eXC_RESULT xc_spi_flash_read(uint8_t reg_idx, uint32_t addr, uint8_t *buff,
|
||||
uint16_t size)
|
||||
{
|
||||
eXC_RESULT ret = XR_OK;
|
||||
uint32_t cur_addr = addr;
|
||||
uint32_t end_addr = addr + size;
|
||||
uint16_t rd_len = 0;
|
||||
uint16_t cur_page_num = 0;
|
||||
uint32_t cur_start_psr = 0;
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = {0};
|
||||
uint16_t cur_size;
|
||||
|
||||
while (cur_addr != end_addr) {
|
||||
cur_page_num = CUR_PAGE_NUM(cur_addr);
|
||||
cur_start_psr = CUR_START_PSR(cur_addr);
|
||||
xc_spi_flash_read_page(reg_idx, cur_page_num * FLASH_PAGE_SIZE, temp_buff);
|
||||
if (cur_start_psr) {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE - cur_start_psr, size - rd_len);
|
||||
} else {
|
||||
cur_size = MIN(FLASH_PAGE_SIZE, size - rd_len);
|
||||
}
|
||||
|
||||
memcpy(buff + rd_len, &temp_buff[cur_start_psr], cur_size);
|
||||
cur_addr += cur_size;
|
||||
rd_len += cur_size;
|
||||
}
|
||||
|
||||
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};
|
||||
uint32_t i = 0;
|
||||
|
||||
while (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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#if FAST_SPI
|
||||
eXC_RESULT xc_spi_write_2bytes(uint8_t reg_idx, uint8_t *txdata, uint16_t size)
|
||||
{
|
||||
uint32_t time_out;
|
||||
uint32_t temp_data;
|
||||
uint16_t idx_8bit = 0;
|
||||
uint16_t idx_16bit = 0;
|
||||
uint8_t remain_size = size % 2;
|
||||
uint16_t allign_16bit_size = size >> 1;
|
||||
|
||||
if (size == 0)
|
||||
return XR_ERROR;
|
||||
xc_spi_enable(reg_idx, SSI_CTRL0_DFS_LEN_16BIT);
|
||||
while(!(spi_sts_get(reg_idx)&(1<<SSI_TFE_POS)));
|
||||
while(idx_16bit < allign_16bit_size)
|
||||
{
|
||||
temp_data = ((txdata[idx_8bit] << 8) | txdata[idx_8bit+1]);
|
||||
spi_data_set(reg_idx, temp_data);
|
||||
idx_16bit++;
|
||||
idx_8bit+=2;
|
||||
}
|
||||
if (remain_size != 0 ){
|
||||
for (uint8_t i = 0; i < remain_size; i++){
|
||||
temp_data |= (txdata[idx_8bit + i] << (8 - 8 * i));
|
||||
}
|
||||
while (!(spi_sts_get(reg_idx) & (1<<SSI_TFNF_POS)));
|
||||
spi_data_set(reg_idx, temp_data);
|
||||
}
|
||||
while (!(spi_sts_get(reg_idx) & (1<<SSI_TFE_POS)) ||
|
||||
(spi_sts_get(reg_idx) & (1<<SSI_BUSY_POS)))
|
||||
{
|
||||
time_out++;
|
||||
if (time_out >= SPI_WAIT_TIMEOUT) {
|
||||
DEBUG("func=%s,line=%d,timeout\n", __func__, __LINE__);
|
||||
return XR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
return XR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @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);
|
||||
}
|
||||
|
||||
#endif // XC_CHECK(XC_SPI_ENABLED)
|
||||
Reference in New Issue
Block a user