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.

SPI Character Length and FIFO Question F28075

Hey all,


This is hopefully a fairly straightforward question, but after reading the TRM for the F28075 the answer wasn't spelled out explicitly so I thought someone on here could verify.


I am looking to talk over SPI to a 16 bit external DAC that is looking for a 24 bit word to for each data point it puts out.  I was planning to parse the data and configuration bits into 3 separate 8 bit chunks, and put them into 2 different FIFO word registers and the SPITXBUF register and let the SPI peripheral shift them out sequentially without delay.  I know that the character length is set by the SPICHAR bit in the SPICCR register, I just want verification that if I set the SPICHAR length to 8 bits and that if I used the 3 word registers that I would get a 24 sequential bit stream.  The documentation for the FIFO isn't very specific about this.  I want to know if the hardware forces the FIFO register to shift out all 16 bits before moving on to the next FIFO register in the sequence.


Best regards,

Lance

  • Lance,

    You will want to use 3 writes to the SPITXBUF. You will left-shift the 8-bit word to be transmitted in each write. Essentially, the first 16-bit word will be transferred to the shift register where the upper 8 bits will be shifted out to the data line.then the SPI will copy the next 16-bit word in the FIFO to the shift register and repeat. The F2807x SPI has a 16-level FIFO regardless of the word size. For example, you can store sixteen 2-bit words, or you can store sixteen 16-bit words in the FIFO without any data packing.

    Thanks,
    Mark
  • Mark,

    I think I understand what you are saying.  Here is a quick bit of code I put together which I believe should work (may need refinement) as I want based on your advice.

    I configure the SPI peripheral for 8 bit characters and FIFO operation.  I also include code to parse the 16 bit data to send it out in separate chunks left justified.  I execute 3 sequential writes to the SPITXBUF register to start filling up the FIFO. Based on my understanding from your explanation this would end up creating the continuous 24-bit long data stream on the SPISIMOA pin.  Is that correct?

    Somewhere else in code I would plan to use the interrupt flag to tell when the SPI module has finished sending out the data, but omitted it. 

    void SPI_DAC_CNF(){
    //SPI Register Configuration
        //SPICCR Registers
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = 0x7;  //8-bit characters
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;  //Clock polarity (data out on rising clock edge)
        
        //SPICTL Reigsters
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;    //Configure as a master to transmit on SPISIMOA
        SpiaRegs.SPICTL.bit.CLK_PHASE = 1;    //Clock phase, half cycle offset
        SpiaRegs.SPICTL.bit.TALK = 1;    //Enable data transmit via SPI
        SpiaRegs.SPICTL.bit.SPIINTENA = 1;     //Enable SPI interrupts
        
        //SPIPRI Registers
        SpiaRegs.SPIPRI.bit.STEINV = 0;        //SPISTE bar acitve low
        SpiaRegs.SPIPRI.bit.TRIWIRE = 0;    //Normal 4 wire operation
        
        //SPIBRR Registers
        SpiaRegs.SPIBRR.all = 0;    //Set Baud rate to max rate, 15Mbaud
        
        //SPI FIFO Registers
        SpiaRegs.SPIFFTX.all = 0xC020;    //Set TX FIFO to throw a flag when the TX FIFO is empty
        SpiaRegs.SPIFFRX.all = 0x0023;    //Set RX FIFO to throw a flag when the RX FIFO has 3 entries
        SpiaRegs.SPIFFCT.all = 0x00;
        
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;        //Enable SPI
        SpiaRegs.SPIFFTX.bit.TXFIFO=1;
        SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;
    }

    void SPI_DAC_WRITE(unsigned int data)
    {
        unsigned int address; //address variable, just a dummy varaible for this example.
        
        address = address << 8;  //left shift to make tx buff happy.
        
        //Conditioning on input data to be ready for 8 bit TX FIFO
        unsigned int arraydata[2];
        arraydata[0] = data << 8;
        arraydata[1] = data >> 8;
        arraydata[1] = arraydata[1] << 8;
        
        //Load up the TX buffer and FIFO with the 3 8-bit chunks to have SPI peripheral clock out the 24-bit string
        SpiaRegs.SPITXBUF = address;        //8 bit DAC address
        SpiaRegs.SPITXBUF = arraydata[1];    //8 MSBs of data
        SpiaRegs.SPITXBUF = arraydata[0];    //8 LSBs of data
    }

  • Lance,

    You are correct.

    I am not sure what you are trying to do here:

        arraydata[0] = data << 8;
        arraydata[1] = data >> 8;
        arraydata[1] = arraydata[1] << 8;
    

    Really you can just do something like this and accomplish the same thing.

    [1]    arraydata[0] = data << 8;
    [2]    arraydata[1] = data & 0xFF00;
    

    Line 1 is the same. you are shifting the LSB to the MSB to be copied into the FIFO. Line 2 is more clear. In reality, you could just save the bitwise operation and just write 'data' to arraydata[1], since the SPI will only transmit the MSB it really doesn't matter what the LSB is.

    Thanks,
    mark