V1.0
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);
|
||||
}
|
||||
Reference in New Issue
Block a user