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.

MIBSPI clarification

Hi,

I have 2 questions relating to multi-buffered SPI.

1. When the MIBSPIE[0] is set, can the SPI module still be used in compatibility mode? i.e. will a write to DAT1 still result in transmission of SPI data? I have an SPI ADC which I would like to configure in compatibility mode, then handle reading of conversions using multi-buffered mode, with TG being triggered by a falling edge of the ADC's DRDY output which is connected to GIOA[7].

2. What is required in the BUFID field in DMAxCTRL register? I have a single transfer group which contains 4 bytes of data that need to be clocked out of the TMS570 in order to read back 4 bytes of conversion data from the ADC which I then wish to DMA to a circular buffer which will hold conversion data ready to be processed periodically by the application.  This TG is simply triggered repeatedly by the DRDY signal from the ADC. Does BUFID correspond to PSTARTx in TGxCTRL or is this something different?

I have successfully used DMA with data received via SCI interface so I think I am OK with that side of things, it is just mapping the MIBSPI DMA requests to the DMA module channels that I am not sure about.

Thank you for your help.

Mark.

  • Hi Mark,

      1. When you are in MultiBuffer mode you can not use DAT1.

      2. The BUFID corresponds to the last buffer in the transfer group. Since you have allocated 4 buffers in the transfer group then the BUFID will be 3. Please also reference the below app note about MibSPI DMA transfer.

  • Thanks Charles.

    I will configure the device in compatibility mode before enabling multibuffered SPI.

    The application note was very useful. I have one more question relating to the DMA settings.

    SPI communication with the ADC is 8-bit, with 4 8-bit transfers giving a single conversion (8 bits status, including channel id and 24-bits conversion data).

    So for each conversion I need the LSB of the data field for 4 consecutive buffers.

    I assume I need to set read element size as 8-bit access and write element size at 32-bit access, but I am not clear what the source and destination element and frame offsets need to be set to to achieve the correct packing in main memory.

    Also is it possible to set the source address as the lower byte of &spiRAM->rx[0].data or does this address have to be on a 16-bit boundary?

    Thanks,

    Mark.

  • Mark,

    You are basically right with your analysis, here are coem comments.

    In case you use the MIBSPI in multi buffer mode the incoming data from your ADC will be stored in the 32-bit receive buffers. Each of the receive buffers are split into a 16-bit control field and the 16-bit receive field. In case you configure the MIBSPI for 8-bit transfers the receive field will only hold 8-bit of valid data. So you would need to configure the DMA for 8-bit reads and you could configure it for 32-bit writes, to let the DMA make the data packing and reduce the required bandwidth to write to the embedded SRAM.

    Please note that the DMA needs both the read and write address to be aligned to the read and write element size. Thus you can't do a 16-bit read on a 8-bit boundary like 0x3. So setting the read address to the lower byte of the data field will work, as long as you use a 8-bit read element size.

    The source address element index for read needs to be set to 4 to increment the DMA read address by 4 bytes. All other indexes/offsets are dependent on your setup. The destination address element index will most likely also be set to 4 or Post incremented to be used, to increment the write address by 4 bytes.

    Best Regards,
    Christian

  • Thanks Christian, that makes sense.

    In the example code provided with the application note posted by Charles, the TGxCTRL registers for a number of transfer groups are written and a function mibspiSetData() is provided to write to the Tx data buffers. This function assumes there are 8 configured TGs and in case of TGCTRL[7] uses LTGPEND to determine the number of buffers to be written and otherwise uses the PSTART field from TGCTRL[n+1].

    Is this configuration of all TGs necessary? If I configure only TG0 with PSTART of 0x0 and set LTGPEND to 0x3 what will happen when a transfer is triggered? Will it fail because PSTART for TG1 is set to default value of 0, or will it transfer until the address (offset) in LTGPEND?

    Thanks for any help.

    Mark.

  • Hi,

    I am still a little unclear about this last point.

    When a transfer group is triggered, how does internal logic of the MIBSPI know how many buffers to transfer before it stops?

    Are the buffers shifted out until the start buffer of the next TG is reached? In which case what happens if the TGCTRL register for the next TG has not been configured and so the start address of the next TG is left at default of 0? Does the MIBSPI then shift either to the buffer configured in LTGRPEND or the end of the ram if this is not configured?

    I only want to configure a single transfer group for this application, but I would like to understand the operation of the module more generally in respect of how the number of buffers to be transferred is determined.

    Thanks,

    Mark.

  • Mark,

    So first we've found that the MibSPI only seems to poll the buffers of the highest priority transfer group that is enabled.

    I think the documentation is written such that if you use certain BUFMODE settings the SPI might decide it's finished temporarily with the current transfer group (paused waiting for service) and then start servicing the next priority group. But from what we've found by use it doesn't work this way. I think we will have some documentation updates to make.

    Then to your original question - let's say the MibSPI is operating within a certain transfer group. Then that TG has a list of buffers on which it operates.

    Think about each of these buffers as a sort of 'shadow' register for SPIDAT and SPIBUF. The data is written to the 'transmit data register RAM' along with format, mode, and chip select number information. The receive buffer data register RAM contains the 'status' of the buffer along with the data received by the SPI after a transmistion completes.

    When you read/write each individual buffer - the status in the receive buffer register is updated in terms of RXEMPTY & TXFULL just like it would be if you read/wrote directly to SPIDAT and SPIBUF. Except that these are shadow copies of those two registers.
    It is important that you do not write or read directly to/from SPIDAT and SPIBUF when in the multibuffer mode. All accesses must go through the RAMs.

    Now the MibSPI starts evaluating these shadowed copies of SPIDAT and SPIBUF in order beginning with the buffer that the TG points to.

    The BUFMODE then determines what the MibSPI should do based on whether it's been serviced for transmit and/or receive.

    There are a couple different use models intended.

    First would be to periodically poll an external SPI based peripheral like a temp sensor and copy it's values into the MibSPI RAM.
    In that case you may not want to wait for the CPU to read the temperature. You just want to keep a recent copy of the temperature value in the MibSPI RAM in case the CPU needs it.

    So in that case you could set the BUFMODE to continuous (#4) and every time the TG is triggered it would read the external device and update the sensor information - regardless of whether the CPU has read the previous value. i.e. it doesn't wait on either TXFULL or RXEMPTY .. it always *transmits* the same sequence from the MibSPI tx buffer RAM and writes over previous data in the receive buffer RAM.

    The opposite would be a block transfer example - where you need to move a large block of data from an external device without dropping any samples. For that mode you may want to set the buffers up as 'suspend single transfer overwrite protect' which is a long winded way of telling the MibSPI not to start the transfer again until the CPU or DMA has both written new data to the TX buffer RAM *and* read the old data from the RX buffer RAM.

    The other modes of BUFMODE are variations - for example you may not be receiving any data so you might just do 'suspend single transfer' (bufmode 5) so that you ignore rx overruns.

    I would recommend against trying to use more than one transfer group at a time and avoid 'lock' at least until you have something working.