OsvvmLibraries icon indicating copy to clipboard operation
OsvvmLibraries copied to clipboard

SPI Peripheral can only send a single byte

Open SkydiverTricky opened this issue 10 months ago • 2 comments

Looking at the code in SpiPeripheral : https://github.com/OSVVM/SPI_GuyEschemann/blob/77d1e30c494d0e6032918cde70c179a5b575976a/src/SpiPeripheral.vhd#L267

It appears this code can only send a single byte without raising and re-asserting CSEL. It is pretty common in a SPI interface to send multiple bytes per transaction for as long as the controller holds CSEL low.

Currently, the while loop is exited while, but it then has a wait until CSEL = '0'

which requires an event on CSEL to re-enter and send more data. This line should probably be:

if CSEL = '1' then wait until CSEL = '0' end if;

but with this, you will need to somehow catch when CSEL rises to 1 if the transaction is actually ended at the end of the current byte. You could probably do this with the following code:

if CSEL = '1' then 
    wait until CSEL = '0'; 
    bitIdx  := TxData'high;
end if;

if OptSpiMode = 0 or OptSpiMode = 3 then
    wait until falling_edge(SCLK) or CSEL = '1';
else
    wait until rising_edge(SCLK) or CSEL = '1';
end if;

if CSEL = '1' then
    next;
end if;

if bitindex = TxData'high then
    if not Empty(TransmitFifo) then
        TxData := Pop(TransmitFifo);
    else
        TxData := (others => 'X');  -- X would be better here IMO to differentiate from actual data transmission
    end if;
end if;

while CSEL = '0' and BitIdx >= 0 loop
    POCI <= TxData(BitIdx) when OptSpiMode = 0 or OptSpiMode = 2;

    if OptSpiMode = 0 or OptSpiMode = 3 then
        wait until falling_edge(SCLK);
    else
        wait until rising_edge(SCLK);
    end if;

    POCI <= TxData(BitIdx) when OptSpiMode = 1 or OptSpiMode = 3;
    BitIdx := BitIdx - 1;
end loop;

bitIdx  := TxData'high when  bitIdx < 0;

SkydiverTricky avatar Jan 03 '25 10:01 SkydiverTricky