Other Parts Discussed in Thread: C2000WARE
“线程:C2000WARE”中讨论的其它部件
我正在寻找一种算法或一个示例,说明如何在 启用 FIFO 的情况下多写16个单词。 我将在 我们的设计中添加16MBit SPI EEPROM,并希望能够连续书写16个以上的单词。 如果需要禁用 FIFO 才能实现此目的,这也是可以的。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Other Parts Discussed in Thread: C2000WARE
我正在寻找一种算法或一个示例,说明如何在 启用 FIFO 的情况下多写16个单词。 我将在 我们的设计中添加16MBit SPI EEPROM,并希望能够连续书写16个以上的单词。 如果需要禁用 FIFO 才能实现此目的,这也是可以的。
你好,杰弗里,
向 FIFO 写入的字数不能超过16个,因为这超出了限制。 您可以通过连续写入 FIFO 来保持 FIFO 已满,但要先检查 FIFO 是否已满。 下面是我们的 C2000ware 中包含的用于新一代设备的一个例程,但您可以为 F2808创建自己的软件。
//*****************************************************************************
//
//! Waits for space in the FIFO and then puts data into the transmit buffer.
//!
//! \param base specifies the SPI module base address.
//! \param data is the left-justified data to be transmitted over SPI.
//!
//! This function places the supplied data into the transmit buffer of the
//! specified SPI module once space is available in the transmit FIFO. This
//! function should only be used when the FIFO is enabled.
//!
//! \note The data being sent must be left-justified in \e data. The lower
//! 16 - N bits will be discarded where N is the data width selected in
//! SPI_setConfig(). For example, if configured for a 6-bit data width, the
//! lower 10 bits of data will be discarded.
//!
//! \return None.
//
//*****************************************************************************
static inline void
SPI_writeDataBlockingFIFO(uint32_t base, uint16_t data)
{
//
// Check the arguments.
//
ASSERT(SPI_isBaseValid(base));
//
// Wait until space is available in the receive FIFO.
//
while(SPI_getTxFIFOStatus(base) == SPI_FIFO_TXFULL)
{
}
//
// Write data to the transmit buffer.
//
HWREGH(base + SPI_O_TXBUF) = data;
}
//*****************************************************************************
//
//! Get the transmit FIFO status
//!
//! \param base is the base address of the SPI port.
//!
//! This function gets the current number of words in the transmit FIFO.
//!
//! \return Returns the current number of words in the transmit FIFO specified
//! as one of the following:
//! \b SPI_FIFO_TX0, \b SPI_FIFO_TX1, \b SPI_FIFO_TX2, \b SPI_FIFO_TX3,
//! ..., or \b SPI_FIFO_TX16
//
//*****************************************************************************
static inline SPI_TxFIFOLevel
SPI_getTxFIFOStatus(uint32_t base)
{
//
// Check the arguments.
//
ASSERT(SPI_isBaseValid(base));
//
// Get the current FIFO status
//
return((SPI_TxFIFOLevel)((HWREGH(base + SPI_O_FFTX) & SPI_FFTX_TXFFST_M) >>
SPI_FFTX_TXFFST_S));
}感谢 Gus 的回应,但我终于找到了解决方案,如果有其他人感兴趣,这就是我的答案。
要 能够连续写入大于16个单词的 SPI,请使用以下算法:
void _spi_write(volatile struct SPI_REGS* spir, Uint16* data, Uint16 numbytes)
{
// Writes to SPITXBUF must be left-justified for less than 16 bits per 'character' to send.
// Filling the SPITXBUF auto sends the byte to SPIDAT (assuming no pending data in SPIDAT)
// and then onto the data out line
Uint16 i, j = 0;
Uint16 numFullFifo = numbytes / SPI_FIFO_SIZE;
Uint16 numLessFifo = numbytes % SPI_FIFO_SIZE;
// Need to be able to write consecutive words > 16 in size
do
{
if (j < numFullFifo)
{
for (i = 0; i < SPI_FIFO_SIZE; i++)
{
// spir->SPICCR.bit.SPICHAR + 1 since SPICHAR of 0 is 1 bit, 1 is 2 bits
// so a SPICHAR of 7 is really 8 bits
spir->SPITXBUF = data[i + (j * SPI_FIFO_SIZE)] << (16 - (spir->SPICCR.bit.SPICHAR + 1));
}
// wait until bits have shifted out
while(spir->SPIFFTX.bit.TXFFST != 0) { }
j++;
}
else
{
if(numLessFifo > 0)
{
for (i = 0; i < numLessFifo; i++)
{
// spir->SPICCR.bit.SPICHAR + 1 since SPICHAR of 0 is 1 bit, 1 is 2 bits
// so a SPICHAR of 7 is really 8 bits
spir->SPITXBUF = data[i + (j * SPI_FIFO_SIZE)] << (16 - (spir->SPICCR.bit.SPICHAR + 1));
}
// wait until bits have shifted out
while(spir->SPIFFTX.bit.TXFFST != 0) { }
}
break;
}
} while(true);
DELAY_US(SPI_INTERMSG_DELAY);
}
但是,如果您需要读取16个以上的单词,则上述算法将不适用于“While (SPIR->SPIFFRX.Bit.RXFFST != numbytes)”。 它只读了最后16个字。 要读取超过16个单词(如 EEPROM 块),您需要执行以下操作:
Uint16 Read_I2CEEPROM(Uint16 address, Uint16* data, Uint16 numbytes) {
Uint16 i = 0;
Uint16 fullwords = numbytes / MAX_I2C_DATA_BYTES;
Uint16 finalbytes = numbytes % MAX_I2C_DATA_BYTES;
Uint16 results = DATA_SUCCESS;
if(results == DATA_SUCCESS)
{
do
{
if (i < fullwords)
{
results |= EEPROM_Read_Memory((address + (i * MAX_I2C_DATA_BYTES)), data, MAX_I2C_DATA_BYTES);
if(results != DATA_SUCCESS)
break;
ServiceDog();
i++;
}
else if(finalbytes > 0)
{
results |= EEPROM_Read_Memory((address + (i * MAX_I2C_DATA_BYTES)), data, finalbytes);
if(results != DATA_SUCCESS)
break;
break;
}
} while(true);
}
return results;
}很高兴您能找到适合您的产品。 请注意,SPI_WRITE 函数看起来过于复杂。 只要 TX FIFO 未满,您就可以向其写入单词。 我将按如下方式编写 SPI_WRITE:
对于(i = 0;i <数字字节;I++)
{
SPIR->SPITXBUF =数据[i] <<(16 -(SPIR->SPICCR.bit.SPICHAR + 1));
while (SPIR->SPIFFTX.Bit.TXFFST == SPI_FIF_SIZE);
}
对 TXFFST 的检查将等到 TX FIFO 中至少有一个点可用。