v1
This commit is contained in:
@@ -0,0 +1,593 @@
|
||||
/*!
|
||||
* \file xc6xxx_fmc_spi.c
|
||||
*
|
||||
* \brief Target xc6xxx hal fmc 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_fmc_spi.h"
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void *ram_memcpy_bytes(void *dst, const void *src, int size)
|
||||
{
|
||||
if(dst == NULL || src == NULL || size <= 0)
|
||||
return NULL;
|
||||
|
||||
char *pdst = (char *)dst;
|
||||
char *psrc = (char *)src;
|
||||
|
||||
if(pdst > psrc && pdst < psrc + size) {
|
||||
pdst = pdst + size - 1;
|
||||
psrc = psrc + size - 1;
|
||||
while(size--)
|
||||
*pdst-- = *psrc--;
|
||||
} else {
|
||||
while(size--)
|
||||
*pdst++ = *psrc++;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_Status_Wait_Idle(void)
|
||||
{
|
||||
uint32_t reg = 0;
|
||||
do {
|
||||
__READ_REG32(BLE_COMN_AGC_REG_OUT0, reg);
|
||||
} while(!(reg & FMC_IDLE_Msk));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_WriteNByte(uint8_t* txdata, uint16_t len)
|
||||
{
|
||||
if(len == 0) return;
|
||||
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 4;
|
||||
uint16_t cnt = len / 4;
|
||||
uint32_t mid_data[64+1] = { 0 };
|
||||
|
||||
if(cnt != 0) {
|
||||
for(n=0; n<cnt; n++) {
|
||||
mid_data[n] = ((txdata[n*4] << 24) | (txdata[n*4+1] << 16) |
|
||||
(txdata[n*4+2] << 8) | txdata[n*4+3]);
|
||||
}
|
||||
}
|
||||
|
||||
if(remain != 0) {
|
||||
for(n=0; n<remain; n++) {
|
||||
mid_data[cnt] |= (txdata[cnt*4+n] << (24-8*n));
|
||||
}
|
||||
}
|
||||
|
||||
if(cnt != 0) {
|
||||
if(remain != 0)
|
||||
cnt = cnt + 1;
|
||||
for(n=0; n<cnt; n++)
|
||||
__FMC_SPI_SendByte(mid_data[n]);
|
||||
} else {
|
||||
__FMC_SPI_SendByte(mid_data[0]);
|
||||
}
|
||||
|
||||
while(!(*FMC_SSI_STS & FMC_SPI_STS_REG_FLAG_TFE) ||
|
||||
(*FMC_SSI_STS & FMC_SSI_STS_BUSY));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_ReadNByte(uint8_t* rxdata, uint16_t len)
|
||||
{
|
||||
if(len == 0) return;
|
||||
|
||||
uint16_t n;
|
||||
uint8_t remain = len % 4;
|
||||
uint16_t cnt = len / 4;
|
||||
uint32_t mid_data = 0;
|
||||
|
||||
if(cnt != 0) {
|
||||
for(n=0; n<cnt; n++) {
|
||||
mid_data = __FMC_SPI_RecvByte( );
|
||||
// printf("0_rcv: 0x%08x\n", mid_data);
|
||||
rxdata[n*4] = mid_data >> 24;
|
||||
rxdata[n*4+1] = mid_data >> 16;
|
||||
rxdata[n*4+2] = mid_data >> 8;
|
||||
rxdata[n*4+3] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
if(remain != 0) {
|
||||
mid_data = __FMC_SPI_RecvByte( );
|
||||
// printf("1_rcv: 0x%08x\n", mid_data);
|
||||
for(n=0; n<remain; n++) {
|
||||
rxdata[cnt*4+n] = mid_data >> 24;
|
||||
rxdata[cnt*4+1+n] = mid_data >> 16;
|
||||
rxdata[cnt*4+2+n] = mid_data >> 8;
|
||||
rxdata[cnt*4+3+n] = mid_data;
|
||||
}
|
||||
}
|
||||
|
||||
while(*FMC_SSI_STS & FMC_SPI_STS_REG_FLAG_RFNE) {
|
||||
mid_data = __FMC_SPI_RecvByte( );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Enable(uint8_t dfs)
|
||||
{
|
||||
__WRITE_REG32(FMC_SSI_EN, 0);
|
||||
if(dfs != 0x1f) {
|
||||
uint32_t reg= *FMC_SSI_CTRL0;
|
||||
__CLEAR_BIT(reg, (uint32_t)0x1f);
|
||||
__SET_BIT(reg, (uint32_t)dfs);
|
||||
__WRITE_REG32(FMC_SSI_CTRL0, reg);
|
||||
}
|
||||
__WRITE_REG32(FMC_SSI_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Disable(void)
|
||||
{
|
||||
__WRITE_REG32(FMC_SSI_EN, 0);
|
||||
uint32_t reg= *FMC_SSI_CTRL0;
|
||||
__CLEAR_BIT(reg, (uint32_t)0x1f);
|
||||
__SET_BIT(reg, (uint32_t)0x1f);
|
||||
__WRITE_REG32(FMC_SSI_CTRL0, reg);
|
||||
__WRITE_REG32(FMC_SSI_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Init_Oprt(void)
|
||||
{
|
||||
/* BT_CLK 时钟控制寄存器 */
|
||||
__WRITE_REG32(CPR_BT_CLK_CTL, ((1<<4) | ((1<<4)<<16)));
|
||||
/* BT_MODEM_CLK 时钟控制寄存器 */
|
||||
__WRITE_REG32(CPR_BT_MODEM_CTL, ((1<<4) | ((1<<4)<<16)));
|
||||
/* 配置 BT_PCLK_EN 使能 */
|
||||
__SET_BIT(*CPR_CTLAPBCLKEN_GRCTL, ((1<<10) | ((1<<10)<<16)));
|
||||
__WRITE_REG32(CPR_SSI0_MCLK_CTL, ((1<<16) | ((0<<4) | ((1<<16)<<4))));
|
||||
__WRITE_REG32(CPR_RSTCTL_SUBRST_SW, ((0<<2) | ((1<<2)<<16)));
|
||||
__WRITE_REG32(CPR_RSTCTL_SUBRST_SW, ((1<<2) | ((1<<2)<<16)));
|
||||
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
__WRITE_REG32(FMC_SSI_EN, 0);
|
||||
uint32_t reg= *FMC_SSI_CTRL0;
|
||||
__CLEAR_BIT(reg, (uint32_t)0x1f);
|
||||
__SET_BIT(reg, (uint32_t)0x1f);
|
||||
__WRITE_REG32(FMC_SSI_CTRL0, reg);
|
||||
*FMC_SSI_CTRL0 &= ~((uint32_t)0x01 << 14);
|
||||
|
||||
__WRITE_REG32(FMC_SSI_SE, 1);
|
||||
__WRITE_REG32(FMC_SSI_IE, 0);
|
||||
__WRITE_REG32(FMC_SSI_BAUD, 2);
|
||||
__WRITE_REG32(FMC_SSI_TXFTL, 0);
|
||||
__WRITE_REG32(FMC_SSI_RXFTL, 0);
|
||||
__WRITE_REG32(FMC_SSI_EN, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_PowerDown(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[4];
|
||||
|
||||
cmd[0] = 0;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = CMD_PWRDWN;
|
||||
|
||||
FMC_SPI_Enable(0x07);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_WakeUp(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[4];
|
||||
|
||||
cmd[0] = 0;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = CMD_RELEASE_PWRDWN;
|
||||
|
||||
FMC_SPI_Enable(0x07);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE uint8_t FMC_SPI_Flash_Status(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[2] = { 0 };
|
||||
uint8_t sta[4] = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
cmd[0] = CMD_READ_STATUS;
|
||||
cmd[1] = 0xff;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_ReadNByte(sta, sizeof(sta));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
return sta[1];
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_Wait_Busy(void)
|
||||
{
|
||||
while(( FMC_SPI_Flash_Status( ) & 0x01 ));
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_Write_Enable(void)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
uint8_t cmd[4] = { 0 };
|
||||
|
||||
cmd[0] = 0;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = CMD_WRITE_ENABLE;
|
||||
|
||||
FMC_SPI_Enable(0x07);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_Erase_Sector(uint32_t Dst_Addr)
|
||||
{
|
||||
// FMC_Status_Wait_Idle( );
|
||||
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
FMC_SPI_Flash_Write_Enable( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
uint8_t cmd[4] = { 0 };
|
||||
|
||||
cmd[0] = CMD_SECTOR_ERASE;
|
||||
cmd[1] = Dst_Addr>>16;
|
||||
cmd[2] = Dst_Addr>>8;
|
||||
cmd[3] = Dst_Addr;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_WritePage(uint32_t WriteAddr, uint8_t *data, uint16_t size)
|
||||
{
|
||||
if(size > FLASH_PAGE_SIZE)
|
||||
return;
|
||||
|
||||
uint32_t addr = WriteAddr;
|
||||
uint8_t cmd[16+4] = { 0 };
|
||||
|
||||
for(uint8_t i=0; i<16; i++) {
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
FMC_SPI_Flash_Write_Enable( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
cmd[0] = CMD_PAGE_PROGRAM;
|
||||
cmd[1] = addr >> 16;
|
||||
cmd[2] = addr >> 8;
|
||||
cmd[3] = addr;
|
||||
|
||||
ram_memcpy_bytes(&cmd[4], data+i*16, 16);
|
||||
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
|
||||
addr += 16;
|
||||
}
|
||||
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_ReadPage(uint32_t ReadAddr, uint8_t *data, uint16_t size)
|
||||
{
|
||||
if(size > FLASH_PAGE_SIZE)
|
||||
return;
|
||||
|
||||
FMC_Status_Wait_Idle( );
|
||||
|
||||
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;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, 20); //sizeof(cmd)
|
||||
FMC_SPI_ReadNByte(mid, 20); //sizeof(mid)
|
||||
|
||||
ram_memcpy_bytes(&data[rx_idx], mid+4, 16);
|
||||
addr += 16;
|
||||
rx_idx += 16;
|
||||
}
|
||||
|
||||
FMC_SPI_Disable( );
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashWrite(uint32_t writeAddr, uint8_t *buff, uint16_t len)
|
||||
{
|
||||
uint32_t cur_addr = writeAddr;
|
||||
uint32_t end_addr = writeAddr + len;
|
||||
uint16_t wt_len = 0;
|
||||
uint16_t CurPageNum = 0; //本次数据存储所占用的当前页号
|
||||
uint32_t CurStartPsr = 0; //本次地址在 当前页所占的位置
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = { 0 };
|
||||
|
||||
while (cur_addr != end_addr) {
|
||||
/* code */
|
||||
CurPageNum = CUR_PAGE_NUM(cur_addr);
|
||||
CurStartPsr = CUR_START_PSR(cur_addr);
|
||||
FMC_SPI_Flash_ReadPage(CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
|
||||
if(CurStartPsr) {
|
||||
ram_memcpy_bytes(&temp_buff[CurStartPsr], buff+wt_len, (256-CurStartPsr)>len-wt_len? len-wt_len:(256-CurStartPsr));
|
||||
wt_len += wt_len + ((256-CurStartPsr)>len-wt_len? len-wt_len:(256-CurStartPsr));
|
||||
cur_addr += wt_len;
|
||||
} else {
|
||||
ram_memcpy_bytes(temp_buff, buff+wt_len, len-wt_len>256? 256:len-wt_len);
|
||||
cur_addr += (len-wt_len>256? 256:len-wt_len);
|
||||
wt_len += (len-wt_len>256? 256:len-wt_len);
|
||||
}
|
||||
FMC_SPI_Flash_WritePage(CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
|
||||
* @return[out]
|
||||
*
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashRead(uint32_t readAddr, uint8_t *buff, uint16_t len)
|
||||
{
|
||||
uint32_t cur_addr = readAddr;
|
||||
uint32_t end_addr = readAddr + len;
|
||||
uint16_t rd_len = 0;
|
||||
uint16_t CurPageNum = 0; //本次数据存储所占用的当前页号
|
||||
uint32_t CurStartPsr = 0; //本次地址在 当前页所占的位置
|
||||
uint8_t temp_buff[FLASH_PAGE_SIZE] = { 0 };
|
||||
|
||||
while (cur_addr != end_addr) {
|
||||
CurPageNum = CUR_PAGE_NUM(cur_addr);
|
||||
CurStartPsr = CUR_START_PSR(cur_addr);
|
||||
FMC_SPI_Flash_ReadPage(CurPageNum*FLASH_PAGE_SIZE, temp_buff, FLASH_PAGE_SIZE);
|
||||
if(CurStartPsr) {
|
||||
ram_memcpy_bytes(buff, &temp_buff[CurStartPsr], (256-CurStartPsr)>len-rd_len? len-rd_len:(256-CurStartPsr));
|
||||
rd_len += rd_len + ((256-CurStartPsr)>len-rd_len? len-rd_len:(256-CurStartPsr));
|
||||
cur_addr += rd_len;
|
||||
} else {
|
||||
ram_memcpy_bytes(buff+rd_len, temp_buff, len-rd_len>256? 256:len-rd_len);
|
||||
cur_addr += (len-rd_len>256? 256:len-rd_len);
|
||||
rd_len += (len-rd_len>256? 256:len-rd_len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_RUID(uint8_t *ruid)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
uint8_t cmd[21] = { 0 };
|
||||
uint8_t id[21] = { 0 };
|
||||
|
||||
cmd[0] = CMD_RUID;
|
||||
cmd[1] = 0xff;
|
||||
cmd[2] = 0xff;
|
||||
cmd[3] = 0xff;
|
||||
cmd[4] = 0xff;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
|
||||
FMC_SPI_ReadNByte(id, sizeof(id));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
ram_memcpy_bytes(ruid, &id[5], 16);
|
||||
}
|
||||
|
||||
/**
|
||||
****************************************************************************************
|
||||
* @brief
|
||||
*
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
****************************************************************************************
|
||||
*/
|
||||
__RAM_CODE void FMC_SPI_Flash_RDID(uint8_t *rdid)
|
||||
{
|
||||
FMC_Status_Wait_Idle( );
|
||||
FMC_SPI_Flash_Wait_Busy( );
|
||||
|
||||
uint8_t cmd[4] = { 0 };
|
||||
uint8_t id[4] = { 0 };
|
||||
|
||||
cmd[0] = CMD_RDID;
|
||||
cmd[1] = 0xff;
|
||||
cmd[2] = 0xff;
|
||||
cmd[3] = 0xff;
|
||||
|
||||
FMC_SPI_Enable(0x1f);
|
||||
FMC_SPI_WriteNByte(cmd, sizeof(cmd));
|
||||
|
||||
FMC_SPI_ReadNByte(id, sizeof(id));
|
||||
FMC_SPI_Disable( );
|
||||
|
||||
ram_memcpy_bytes(rdid, &id[1], 3);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*!
|
||||
* \file xc6xxx_fmc_spi.h
|
||||
*
|
||||
* \brief The header of xc6xxx_fmc_spi.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __XC6xxx_FMC_SPI_H_
|
||||
#define __XC6xxx_FMC_SPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
#define __RAM_CODE __attribute__((section("ram_code")))
|
||||
|
||||
#define __WRITE_REG32(REG, VAL) ((*REG) = (VAL))
|
||||
#define __READ_REG32(REG, VAL) ((VAL) = (*REG))
|
||||
#define __SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
#define __CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
// Register Address Definition
|
||||
#define CPR_BASE 0x40000000UL
|
||||
#define FMC_BASE 0x51000000UL
|
||||
#define BLE_COMMON_BASE 0x53022000UL
|
||||
|
||||
#define CPR_BT_CLK_CTL ((volatile uint32_t *)(CPR_BASE + 0x40))
|
||||
#define CPR_BT_MODEM_CTL ((volatile uint32_t *)(CPR_BASE + 0x48))
|
||||
#define CPR_SSI0_MCLK_CTL ((volatile uint32_t *)(CPR_BASE + 0x50))
|
||||
#define CPR_CTLAPBCLKEN_GRCTL ((volatile uint32_t *)(CPR_BASE + 0x70))
|
||||
#define CPR_RSTCTL_SUBRST_SW ((volatile uint32_t *)(CPR_BASE + 0x104))
|
||||
|
||||
#define FMC_SSI_CTRL0 ((volatile uint32_t *)(FMC_BASE + 0x00))
|
||||
#define FMC_SSI_CTRL1 ((volatile uint32_t *)(FMC_BASE + 0x04))
|
||||
#define FMC_SSI_EN ((volatile uint32_t *)(FMC_BASE + 0x08))
|
||||
#define FMC_SSI_SE ((volatile uint32_t *)(FMC_BASE + 0x10))
|
||||
#define FMC_SSI_BAUD ((volatile uint32_t *)(FMC_BASE + 0x14))
|
||||
#define FMC_SSI_TXFTL ((volatile uint32_t *)(FMC_BASE + 0x18))
|
||||
#define FMC_SSI_RXFTL ((volatile uint32_t *)(FMC_BASE + 0x1C))
|
||||
#define FMC_SSI_TXFL ((volatile uint32_t *)(FMC_BASE + 0x20))
|
||||
#define FMC_SSI_RXFL ((volatile uint32_t *)(FMC_BASE + 0x24))
|
||||
#define FMC_SSI_STS ((volatile uint32_t *)(FMC_BASE + 0x28))
|
||||
#define FMC_SSI_IE ((volatile uint32_t *)(FMC_BASE + 0x2C))
|
||||
#define FMC_SSI_DATA ((volatile uint32_t *)(FMC_BASE + 0x60))
|
||||
|
||||
|
||||
#define BLE_COMN_AGC_REG_OUT0 ((volatile uint32_t *)(BLE_COMMON_BASE + 0x28))
|
||||
|
||||
#define FMC_IDLE_Pos (31U)
|
||||
#define FMC_IDLE_Msk (1UL << FMC_IDLE_Pos)
|
||||
#define FMC_IDLE_STATUS FMC_IDLE_Msk
|
||||
|
||||
#define FMC_SSI_STS_BUSY (1UL)
|
||||
|
||||
#define FMC_SSI_STS_REG_TFE_Pos (2UL)
|
||||
#define FMC_SSI_STS_REG_TFE_EMPTY (1UL << FMC_SSI_STS_REG_TFE_Pos) /*!< 发送 FIFO 空. */
|
||||
#define FMC_SPI_STS_REG_FLAG_TFE ((uint16_t)FMC_SSI_STS_REG_TFE_EMPTY)
|
||||
|
||||
#define FMC_SSI_STS_REG_RFNE_Pos (3UL) /*!< Position of RFNE field. */
|
||||
#define FMC_SSI_STS_REG_RFNE_NOT_EMPTY (1UL << FMC_SSI_STS_REG_RFNE_Pos) /*!<接收 FIFO 非空 */
|
||||
#define FMC_SPI_STS_REG_FLAG_RFNE ((uint16_t)FMC_SSI_STS_REG_RFNE_NOT_EMPTY)
|
||||
|
||||
#define CMD_READ_DATA (uint8_t)0x03
|
||||
#define CMD_READ_STATUS (uint8_t)0x05
|
||||
#define CMD_CHIP_ERASE (uint8_t)0xc7
|
||||
#define CMD_WRITE_ENABLE (uint8_t)0x06
|
||||
#define CMD_WRITE_DISABLE (uint8_t)0x04
|
||||
#define CMD_PAGE_PROGRAM (uint8_t)0x02
|
||||
#define CMD_BLOCK_ERASE (uint8_t)0xD8
|
||||
#define CMD_SECTOR_ERASE (uint8_t)0x20
|
||||
#define CMD_PAGE_ERASE (uint8_t)0x81
|
||||
#define CMD_RELEASE_PWRDWN (uint8_t)0xAB
|
||||
#define CMD_PWRDWN (uint8_t)0xB9
|
||||
#define CMD_RUID (uint8_t)0x4B
|
||||
#define CMD_RDID (uint8_t)0x9F
|
||||
|
||||
#define FLASH_PAGE_SIZE 256
|
||||
|
||||
#define CUR_PAGE_NUM(addr) (addr/FLASH_PAGE_SIZE)
|
||||
#define CUR_START_PSR(addr) (addr%FLASH_PAGE_SIZE)
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Inline Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
__RAM_CODE static inline void __FMC_SPI_SendByte(uint32_t byte)
|
||||
{
|
||||
*FMC_SSI_DATA = byte;
|
||||
}
|
||||
|
||||
__RAM_CODE static inline uint32_t __FMC_SPI_RecvByte(void)
|
||||
{
|
||||
return (uint32_t)(*FMC_SSI_DATA);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
__RAM_CODE void FMC_SPI_Init_Oprt(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_PowerDown(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_WakeUp(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_Wait_Busy(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_Write_Enable(void);
|
||||
__RAM_CODE void FMC_SPI_Flash_Erase_Sector(uint32_t Dst_Addr);
|
||||
__RAM_CODE void FMC_SPI_Flash_Erase_Page(uint32_t Dst_Addr);
|
||||
__RAM_CODE void FMC_SPI_Flash_WritePage(uint32_t WriteAddr, uint8_t *data, uint16_t size);
|
||||
__RAM_CODE void FMC_SPI_Flash_ReadPage(uint32_t ReadAddr, uint8_t *data, uint16_t size);
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashWrite(uint32_t writeAddr, uint8_t *buff, uint16_t len);
|
||||
__RAM_CODE uint8_t FMC_SPI_FlashRead(uint32_t readAddr, uint8_t *buff, uint16_t len);
|
||||
__RAM_CODE void FMC_SPI_Flash_RUID(uint8_t *ruid);
|
||||
__RAM_CODE void FMC_SPI_Flash_RDID(uint8_t *rdid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __XC6xxx_FMC_SPI_H_ */
|
||||
Reference in New Issue
Block a user