作者:LYB
功能说明
CY15B104Q 是使用了高级铁电工艺的 4 Mbit 非易失性存储器。 铁电性随机存取存储器 (即 F-RAM)是一种非易失性存储器, 其读和写操作方式与 RAM 一样。它提供 151 年的可靠数据保留 时间,并解决了由串行闪存、 EEPROM 和其他非易失性存储器 造成的复杂性、开销和系统级可靠性的问题。 与串行闪存和 EEPROM 不同的是, CY15B104Q 以总线速度执 行写操作。并且它不会引起任何写操作延迟。在每个字节成功传 输到器件后,数据立即被写入到存储器阵列。这时,可以开始执 行下一个总线周期而不需要轮询数据。此外,与其他非易失性存 储器相比,该产品提供了更多的擦写次数。 CY15B104Q 能够支 持 1014 读 / 写周期,或支持比 EEPROM 多 1 亿次的写周期。 由于具有这些特性,因此 CY15B104Q 适用于需要频繁或快速写 入的非易失性存储器应用。示例的范围包括从数据收集(其中写 周期数量是非常重要的)到满足工业级控制 (其中串行闪存或 EEPROM 的较长写时间会使数据丢失)。 作为硬件替代时, CY15B104Q 为串行 EEPROM 或闪存的用户 提供大量好处。 CY15B104Q 使用高速的 SPI 总线,从而可以改 进F-RAM技术的高速写入功能。 该设备包含一个只读的器件ID, 通过该 ID,主机可以确定制造商、产品容量和产品版本。在 –40 °C 到 +85 °C 的工业温度范围内,该器件规范得到保证。 要获取相关文档的完整列表,请点击此处
引脚定义
存储器架构
访问 CY15B104Q 时,用户可以寻址 512 K 地址的每 8 个数据 位。这些 8 数据位被连续移入或移出。通过使用 SPI 协议可以访 问这些地址,该协议包含一个芯片选择(用于支持总线上的多个 器件)、一个操作码和一个 3 字节地址。该地址范围的高 5 位都 是 ‘ 无需关注 ’ 的值。 19 位的完整地址独立指定每个字节的地址。 CY15B104Q 的大多数功能可以由 SPI 接口控制或通过板上电路 处理。存储器的访问时间几乎为零,但要考虑串行协议所需要的 时间。因此,该存储器以 SPI 总线的速度进行读 / 写操作。与串 行闪存或 EEPROM 不同的是,不需要轮询设备的就绪条件,这 是因为写操作是以总线速度进行的。新的总线数据操作移入器件 时,写操作已完成。更多详细信息,请参阅 ‘ 接口 ’ 部分介绍 的内容
操作码指令
`#include
#include
#include
#include
#include
#include
#include `
#include
#include
#include
#include
#include
#include
#include
#include "per_task.h"
#include "Assert.h"
#include "DebugPrint.h"
#include "SPITask.h"
#include "CY15B104Q.h"
/***** Variable declarations *****/
Semaphore_Handle semSpiWirte;
Semaphore_Handle semSpiRead;
SPI_Handle spiHandler;
static PIN_State pinState;
static PIN_Handle pinHandle;
static PIN_Config bspCYTable[] = {
BSP_CY15B104Q_WP | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
BSP_CY15B104Q_HOLD | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
BSP_CY15B104Q_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MIN, /* Ext. flash chip select */
PIN_TERMINATE /* Terminate list */
};
static uint8_t spiTxBuf[6] ;
static SPI_Status SPIDataWrite(uint8_t * pData,uint16_t len);
static SPI_Status SPIDataRead(uint8_t * pData,uint16_t *len);
/*-----------------------------------------------------------------------------
Brief :
ParamIn :
ParamIn :
ParamIn :
Return :
------------------------------------------------------------------------------*/
static SPI_Status SPIDataWrite(uint8_t * pData,uint16_t len) {
SPI_Status status;
SPI_Transaction spiTransaction;
// Configure the transaction
ASSERT_FUNCTION_PARAMETER(pData!=NULL,SPI_TRANSFER_CANCELED);
ASSERT_FUNCTION_PARAMETER(len>0,SPI_TRANSFER_CANCELED);
ASSERT_FUNCTION_PARAMETER(lenNULL;
spiTransaction.count=len;
spiTransaction.rxBuf=NULL;
spiTransaction.txBuf=(void *)pData;
SPI_transfer(spiHandler, &spiTransaction);
status= spiTransaction.status;
Semaphore_post(semSpiWirte);
return status;
}
/*-----------------------------------------------------------------------------
Brief :
ParamIn :
ParamIn :
ParamIn :
Return :
------------------------------------------------------------------------------*/
static SPI_Status SPIDataRead(uint8_t * pData,uint16_t *len){
SPI_Transaction spiTransaction;
ASSERT_FUNCTION_PARAMETER(pData!=NULL, SPI_TRANSFER_CANCELED);
ASSERT_FUNCTION_PARAMETER(len>0,SPI_TRANSFER_CANCELED);
ASSERT_FUNCTION_PARAMETER(*lenNULL;
spiTransaction.rxBuf=(void *)pData;
spiTransaction.txBuf=NULL;
SPI_transfer(spiHandler, &spiTransaction);
switch(spiTransaction.status){
case SPI_TRANSFER_CANCELED :
case SPI_TRANSFER_COMPLETED :
break;
case SPI_TRANSFER_STARTED :
break;
case SPI_TRANSFER_FAILED :
Task_sleep(1000 / Clock_tickPeriod);
break;
case SPI_TRANSFER_CSN_DEASSERT :
break;
}
*len=spiTransaction.count;
return spiTransaction.status;
}
/*-----------------------------------------------------------------------------
Brief : Select the external flash on the SensorTag
ParamIn :
ParamIn :
ParamIn :
Return :
------------------------------------------------------------------------------*/
static void CY15B104Q_Select(void)
{
PIN_setOutputValue(pinHandle,BSP_CY15B104Q_CSN,0);
}
/*-----------------------------------------------------------------------------
Brief : Deselect the external flash on the SensorTag
ParamIn :
ParamIn :
ParamIn :
Return :
------------------------------------------------------------------------------*/
static void CY15B104Q_Deselect(void)
{
PIN_setOutputValue(pinHandle,BSP_CY15B104Q_CSN,1);
}
void CY15B104Q_Init(void) {
UInt keytask;
SPI_Params spiParams;
pinHandle = PIN_open(&pinState, bspCYTable);
PIN_setOutputValue(pinHandle,BSP_CY15B104Q_WP,1); //TODO:not sure;
PIN_setOutputValue(pinHandle,BSP_CY15B104Q_HOLD,1); //TODO:not sure;
CY15B104Q_Deselect();
// Semphore for spi read write
keytask = Task_disable();
Semaphore_Params semParams;
Semaphore_Params_init(&semParams);
semParams.mode=Semaphore_Mode_BINARY;
semSpiWirte=Semaphore_create(1,&semParams,NULL);
Semaphore_Params_init(&semParams);
semParams.mode=Semaphore_Mode_BINARY;
semSpiRead=Semaphore_create(0,&semParams,NULL);
// Init SPI and specify non-default parameters
SPI_Params_init(&spiParams);
spiParams.mode = SPI_MASTER;
spiParams.bitRate = CY_SPI_BUAD_RATE; //Maximum bit rate is 4MHz.
spiParams.frameFormat = CY_SPI_MODE3;
spiParams.transferMode = SPI_MODE_BLOCKING;
// Open the SPI and initiate the partial read
SPI_init();
spiHandler=SPI_open(Board_SPI0,&spiParams);
Task_restore(keytask);
// Enable RETURN_PARTIAL7
SPI_control(spiHandler, SPICC26XXDMA_RETURN_PARTIAL_ENABLE, NULL);
Task_sleep(CY_TPU*1000/Clock_tickPeriod);
CY15B104Q_GetDeviceId();
CY15B104Q_Config(0x00);
}
uint8_t CY15B104Q_Config(uint8_t writeStatus){
uint8_t readStatus;
uint16_t readLenth=1;
spiTxBuf[0]=CY_OPCODE_WREN;
spiTxBuf[1]=CY_OPCODE_WRSR;
spiTxBuf[2]=writeStatus;
CY15B104Q_Select();
SPIDataWrite(spiTxBuf,2);
CY15B104Q_Deselect();
spiTxBuf[0]=CY_OPCODE_RDSR;
CY15B104Q_Select();
SPIDataWrite(spiTxBuf,1);
SPIDataRead(&readStatus,&readLenth);
CY15B104Q_Deselect();
return readStatus;
}
void CY15B104Q_Sleep(void){
SPI_Status status;
spiTxBuf[0]=CY_OPCODE_SLEEP;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,1);
CY15B104Q_Deselect();
if(status!=SPI_TRANSFER_COMPLETED) {
}
}
SPI_Status CY15B104Q_ByteWrite(uint32_t address,uint8_t data){
SPI_Status status;
ASSERT_FUNCTION_PARAMETER(address0]=CY_OPCODE_WREN;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,1);
CY15B104Q_Deselect();
spiTxBuf[0]=CY_OPCODE_WRITE;
spiTxBuf[1]=(address>>16)&0x07; //Cypress recommends that these bits be set to 0s to enable seamless transition to higher memory densities.
spiTxBuf[2]=(address>>8)&0xFF;
spiTxBuf[3]=(address)&0xFF;
spiTxBuf[4]=data;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,5);
CY15B104Q_Deselect();
return status;
}
SPI_Status CY15B104Q_ByteRead(uint32_t address,uint8_t *data){
SPI_Status status;
uint16_t length;
ASSERT_FUNCTION_PARAMETER(address0]=CY_OPCODE_READ;
spiTxBuf[1]=(address>>16)&0x07;
spiTxBuf[2]=(address>>8)&0xFF;
spiTxBuf[3]=(address)&0xFF;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,4);
length=1;
if(status!=SPI_TRANSFER_COMPLETED) {
CY15B104Q_Deselect();
return status;
} else {
status=SPIDataRead(data,&length);
}
CY15B104Q_Deselect();
return status;
}
SPI_Status CY15B104Q_BrustWrite(uint32_t startAddr,const uint8_t *pBuf,uint16_t length){
SPI_Status status;
ASSERT_FUNCTION_PARAMETER(startAddrNULL,SPI_TRANSFER_CANCELED);
ASSERT_FUNCTION_PARAMETER(length>0,SPI_TRANSFER_CANCELED);
spiTxBuf[0]=CY_OPCODE_WREN;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,1);
CY15B104Q_Deselect();
spiTxBuf[0]=CY_OPCODE_WRITE;
spiTxBuf[1]=(startAddr>>16)&0x07; //Cypress recommends that these bits be set to 0s to enable seamless transition to higher memory densities.
spiTxBuf[2]=(startAddr>>8)&0xFF;
spiTxBuf[3]=(startAddr)&0xFF;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,4);
if(status!=SPI_TRANSFER_COMPLETED) {
CY15B104Q_Deselect();
return status;
} else {
status=SPIDataWrite((uint8_t *)pBuf,length);
}
CY15B104Q_Deselect();
return status;
}
SPI_Status CY15B104Q_BrustRead(uint32_t startAddr,uint8_t * const pBuf,uint16_t *length){
SPI_Status status;
ASSERT_FUNCTION_PARAMETER(startAddr0]=CY_OPCODE_READ;
spiTxBuf[1]=(startAddr>>16)&0x07;
spiTxBuf[2]=(startAddr>>8)&0xFF;
spiTxBuf[3]=(startAddr)&0xFF;
// spiTxBuf[4]=*length;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,4);
if(status!=SPI_TRANSFER_COMPLETED) {
*length=0;
CY15B104Q_Deselect();
return status;
} else {
status=SPIDataRead(pBuf,length);
CY15B104Q_Deselect();
return status;
}
}
void CY15B104Q_GetDeviceId(void){
uint8_t spiRxBuf[CY_DEVICE_BYTES] ;
uint16_t length=CY_DEVICE_BYTES;
SPI_Status status;
spiTxBuf[0]=CY_OPCODE_RDID;
CY15B104Q_Select();
status=SPIDataWrite(spiTxBuf,1);
status=SPIDataRead(spiRxBuf,&length);
CY15B104Q_Deselect();
if(status!=SPI_TRANSFER_COMPLETED) {
printLine("[CY15B104Q] SPI Operation failed.");
} else {
printHex("[CY15B104Q] FRAM ID ",spiRxBuf,CY_DEVICE_BYTES);
}
}