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.

[参考译文] TMS320F2808:SPI 写入16个以上的(FIFO)字

Guru**** 655270 points
Other Parts Discussed in Thread: C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1077876/tms320f2808-spi-write-of-more-than-16-fifo-words

部件号:TMS320F2808
“线程: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 中至少有一个点可用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢——这同样有效!! :-)