SPI

**SPI** (ingl *Serial Peripheral Interface*) siin on sünkroonse järjestiksuhtluse liidese standard, mida kasutatakse enamasti lühidistantsiliseks suhtluseks ning mis leiab sageli kasutust manussüsteemides. Standardi töötas välja Motorola. SPI võimaldab seadmete vahel täisdupleks režiimis ülem-alluv mudeliga suhtlust. Sageli küündivad SPI suhtluskiirused kümnetesse megahertsidesse.

SPI-d võib kutsuda neljajuhtmeliseks järjestiksiiniks. Seejuures tuleb SPI-d eristada SSI protokollist, mis on samuti neljajuhtmeline järjestiksiin, kuid rakendab diferentsiaalset signaaliedastust simpleks režiimis.

## Liidese signaalid
SPI liidese standard näeb ette signaale:
* SS (ingl *Slave Select*) – ülemseadme (tihti madalaktiivne) juhtsignaal teavitamaks alluvseadet soovist suhtluseks;
* SCK (ingl *Serial Clock*) – ülemseadme (nt mikrokontrolleri) genereeritud taktsignaal;
* MOSI (ingl *Master Out Slave In*) – andmesignaal suunaga ülemalt alluvseadmele;
* MISO (ingl *Master In Slave Out*) – andmesignaal suunaga alluvalt ülemseadmele.
Eelpool nimetatud signaalide nimetused on kõige populaarsemad, kuid levinud on ka teistsugused samatähenduslikud signaalide nimetused:
* SS: S̅S̅, SSEL, CS, C̅S̅, CE, nSS, /SS, SS#;
* SCK: SCLK;
* MOSI: SIMO, SDO, DI, DIN, SI, MTSR;
* MISO: SOMI, SDI, DO, DOUT, SO, MRST.

## Tööpõhimõte
SPI ülem-alluv suhtlusmudelis võib alluvseadmeid olla mitu – ülemseade (sageli mikrokontroller) saab SS signaalidega valida, millise alluvaga suhtlust toimub. Juhul kui kasutusel on vaid üks alluvseade, võib SS signaali jäädavalt madalaks tõmmata, kui alluvseade seda lubab – mõnel seadmel algatab SS signaali frondimuutus mingeid tegevusi. Ülema ja alluva vahelise SPI suhtluse toimimiseks, peab nende seadmete SPI konfiguratsioon olema vastastikku sobituv.

### Taktsignaali polaarsus ja faas

Alluvseadmel on spetsifitseeritud, mis polaarsusega taktsignaali kasutatakse – kas signaal on vaikeolekus, kui taktsignaal on loogiline kõrge või madal. Lisaks on tarvis spetsifitseerida faas – kas andmeid loetakse taktsignaali esimesel või teisel frondil. Levinud tähised nendele sätetele on CPOL ja CPHA.

CPOL (ingl C*lock Polarity*) määrab taktsignaali polaarsuse:
* CPOL = 0 seadistab taktsignaali vaikeolekus loogiliseks madalaks. See tähendab, et taktsignaali esimene front on tõusev ja teine front langev.
* CPOL = 1 seadistab taktsignaali vaikeolekus loogiliseks kõrgeks. See tähendab, et taktsignaali esimene front on langev ja teine front tõusev.
SPI taktsignaali polaarsust saab vajadusel vahetada inverteriga.

CPHA (ingl C*lock Phase*) määrab taktsignaali faasi ehk konfigureerib MISO ja MOSI signaalide andmebittide ajastuse SCK signaali suhtes:
* CPHA = 0 sätte puhul "väljuvat" andmesignaali uuendatakse eelneva taktsignaali tsükli teisel frondil ning "sisenevat" andmesignaali loetakse taktsignaali esimesel frondil. "Väljuva" suuna andmesignaali hoitakse muutumatuna kuni praeguse taktsignaali tsükli teise frondini. Esimese taktsignaali tsükli puhul peab andmebitt MOSI signaalil olema juba enne esimest taktsignaali fronti.
* CHPA = 1 sätte puhul "väljuvat" andmesignaali uuendatakse käesoleva taktsignaali esimesel frondil, "sisenevat" signaali loetakse taktsignaali langeval frondil. "Väljuva" suuna andmesignaali hoitakse muutumatuna kuni järgmise taktsignaali tsükli esimese frondini. Viimase taktsignaali tsükli puhul hoiab alluvseade MISO signaali muutumatuna kuni SS signaal suhtluse lõpetab.
Enamasti hoitakse MISO ja MOSI signaale stabiilsena kogu taktsignaali pooltsükli aja (kuni järgmise taktsignaali frondini) – see annab seadmetele suurema ajaakna andmete lugemiseks.

### SPI režiimid
SPI režiimideks nimetatakse polaarsuse ja faasi erinevaid kombinatsioone. CPOL ja CHPA vaadeldakse kui binaararvu bitte – CPOL määrab režiimi numbri kõrgema biti ja CHPA madalama biti. 

Režiimide nimetamiseks kasutatakse ka ennikuid (CPOL, CHPA). Näiteks ennik (0, 1) tähendab CPOL = 0 ja CHPA = 1.

### Andmevahetus

Lisaks polaarsuse ja faasi seadistamisele tuleb ülemseadmes valida alluvseadmele sobiv taktsignaali sagedus (SPI puhul sageli kuni mitu MHz). Suhtluse algatamiseks tõmbab ülemseade SS signaali loogiliseks madalaks. Mõni seade võib pärast SS langevat fronti vajada teatud ooteaega.

SPI andmevahetus aluseks on tüüpiliselt kaks 8-bitist (või rohkemabitilist) nihkeregistrit – üks ülem- teine alluvseadmes. Nihkeregistrid on ühendatud ringipidi – ülemseadme nihkeregistri väljund on ühendatud MOSI signaaliga alluvseadme registri sisendisse ning alluvseadme nihkeregistri väljund MISO signaaliga ülema nihkeregistri sisendisse.

SPI täisdupleks suhtlus väljendub selles, et iga taktiga nihutatakse üks bit ülemalt alluvale ja vastupidi – tavaliselt välja saadetav bitt on nihkeregistri kõrgeim bitt ning loetud bitt pannakse nihkeregistri madalaimaks bitiks. Sama kehtib ka juhul, kui soovitakse saata andmeid ühes suunas – siis võib vastu võtta sooviv seade teisele tavaliselt nullbitte saata.

Andmeid vahetatakse tavaliselt baidi kaupa seejuures järjestikku võidakse vahetada palju baite. Andmevahetuse lõppedes peatab ülemseade taktsignaali ning tavaliselt vabastab SS signaali tõstes selle loogiliseks kõrgeks. Levinud andmevahetuse andmeühik on ka 16-bitti puuteekraanide kontrollerite puhul ja 12-bitti ADC-de puhul.

### Sõltumatute alluvate konfiguratsioon

SPI sõltumatute alluvatega suhtluseks on ülemseadmel iga alluvseadme jaoks oma SS signaal. Kui alluvseade ei ole parajasti aktiivne (vastav SS signaal on kõrge), peab selle alluvseadme MISO signaal olema kõrgeimpedantsilises olekus, sest kõigi alluvseadmete MISO signaalid on kokku ühendatud. 
### Pärgvõrgu konfiguratsioon

Mõned SPI seadmed võimaldavad pärgvõrk (ingl *daisy chain*) ühendamist. Sel puhul on esimese seadme MISO ühendatud teise MOSI jne. Seadmetes paiknevaid nihkeregistreid mööda saab ülem alluvatele andmed saata ning nihkeregistrite ahelat mööda jõuavad alluvate andmed ka ülemale. Pärgvõrk konfiguratsiooni eeliseks on ülemseadme SS signaalide kokkuhoid.

### Bitthaaval saatmine ja vastuvõtmine ülemseadmes
Kuigi paljudes seadmetes (mikrokontrollerites ja süsteemikiipides) on riistvaraline SPI tugi, võib SPI suhtluse implementeerida ka programmiliselt bitthaaval (ingl *[[bit-banging]]*) andmeid vahetades. Allpool on C keeles kirjutatud näide SPI koodist ülemseadmes, mille puhul SPI konfiguratsioon on CPOL = 0 ja CPHA = 0 ning andmeid vahetatakse baidi kaupa.

CPOL = 0 puhul peab SCK olema madal, enne SS signaali aktiveerimist. SS signaaliga tuleb aktiveerida alluvseade (tavaliselt madalaks tõmmata) ja suhtluse lõppedes vabastada (kõrgeks tõsta). Enamasti lubavad SPI seadmed vahetada SS signaali aktiveeritud oleku ajal minu baiti, seega antud funktsiooni võib välja kutsuda mitu korda.


```c
/*
 * SPI bitthaaval baidi saatmine ja lugemine.
 *
 * CHPA = 0 ja CPOL = 0:
 *   - sisenevad bitid loetakse tõusval SCK frondil.
 *   - väljuvad bitid kirjutatakse langeval SCK frondil.
 *
 * Tagastab loetud baidi.
 */
uint8_t SPI_transfer_byte(uint8_t byte_out)
{
    uint8_t byte_in = 0;
    uint8_t bit;

    for (bit = 0x80; bit; bit >>= 1) {
        /* Kirjuta MOSI liinile bit */
        write_MOSI((byte_out & bit) ? HIGH : LOW);

        /* Viivitus - SCK madal */
        delay(SPI_SCLK_LOW_TIME);

        /* Tõsta SCK signaal kõrgeks */
        write_SCLK(HIGH);

        /* Loe ja jäädvusta MISO liinilt bit */
        if (read_MISO() == HIGH)
            byte_in |= bit;

        /* Viivitus - SCK kõrge */
        delay(SPI_SCLK_HIGH_TIME);

        /* Tõmba SCK madalaks */
        write_SCLK(LOW);
    }

    return byte_in;
}
```


## Eelised ja puudused
### Eelised
*täisdupleks suhtlus;
* tüüpiliselt kõrgem läbilaskevõime kui I²C puhul;
* erinevalt I²C või GPIB või SCSI seadmetest ei vaja SPI alluvad aadressi;
*paindlik protokoll (st vabalt valitav sõne suurus, sisu ja eesmärk);
*vihtne riistvaraline liidestamine:
**tüüpiliselt väiksem voolutarve, võrreldes I²C-ga ja SMBus-ga, tänu elektroonikakomponente väiksemale kogusele (pull-up takistid);
**alluvad töötavad ülema taktsagedusega ja ei vaja eraldi ostsillaatoreid;
**transiivereid pole vaja, aga nendega saab suurendada maksimaalset suhtlusvahemaad.

### Puudused
*nõuab protsessorilt rohkem viike kui I²C;
*tüüpiliselt toetab vaid üht ülemseadet;
*alluv ei saa suhtlusvoo kiirust reguleerida (ülem saab, viivitades taktsignaali teist fronti); 
*puudub riistvaraline seadme tuvastus (ülem saab mitte kellelegi andmeid edastada sellest ise mitte teades);
*protokoll ei määra veakontrolli;
*formaalse standardi puudumise tõttu on seadmete vastavuse kontroll keeruline; 
*võimaldab lühidistantsisidet võrreldes RS-232, RS-485 ja CAN-busi standarditega (aga transiivritega saab seda parandada).

## Kasutusalad
SPI leiab laialdast kasutust manussüsteemides. Paljudes mikrokontrollerites on sisse ehitatud SPI välisseade, mis tavaliselt võimaldab konfigureerimist nii ülem- kui ka alluvseadmeks. SPI suhtlust kasutavad näiteks paljud ADC-d, andurid, puuteekraanid, LCD-kuvar, välkmälud, EEPORM-id ja SD-mälukaardid.

## Standardid
SPI liides on *[[de facto]]* standard, milles ei spetsifitseerita suhtlusprotokolli. Formaalse standardi puudumise tõttu leidub SPI seadmeid, mis on mõeldud vaid ühes suunas andmeid saatma ja seadmeid, mis kasutavad täiendavaid signaale lisaks eelnimetatud neljale. Kasutatakse erinevaid andmeühiku suurus.

Mõned SPI-ga sarnased või sellel põhinevad liidesed:
* MicroWire – toimib nagu SPI režiimis 0, kuid võimaldab ainult poolduplekssidet;
* Dual SPI – kasutab MISO ja MOSI signaale täisdupleksrežiimi asemel pooldupleksina, saates ühe peal täisarvulise indeksiga bitid ja teisel paarituarvulised;
* Quad SPI – toimib samal põhimõttel nagu Dual SPI, aga lisatud on veel kaks andmesidekaablit, mida mööda andmeid saadetakse.

## Viited