AVR I2C: master transmitter => slave receiver

Sziasztok!

AVR MCU-knal (ATmega328p-nel, konkretan) mi a szabalyos uzemmodja annak hogy master modbol a stop kikuldese utan visszavaltsunk slave listener uzembe? Konkrten ez van:

 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

Majd utana valamikor ennek kell kovetkeznie:

 TWAR = (slave_addr<<1);
 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);

Node mikor? A TWSTO kikuldese nem billenti at a TWCR[TWINT]-et (a TWSTA, TWDR-be valo iras, stb modokkal ellentetben), de eme ket utasitast kozvetlenul egymas utan szintugy nem adhatom ki. A workaround az egy parszaz oraciklus hosszu varakozas a ketto kozott, ugy most minden jonak/stabilnak tunik, de az ref. man. semmit nem mond errol... 

Thx, A.

Hozzászólások

Szerkesztve: 2020. 07. 06., h – 17:42

Szia!

A START bit végrehajtását meg kell várni. Ezt a legegyszerűbben a következő sor közbeiktatásával tudod megtenni:

while(!(TWCR & (1<<TWINT))); 

És így pontosan tudod mikor kell továbblépned.

Ebből a szempontból érdemes a Data Sheet 22-10-es ábráját megnézni. Illetve a data shetben lévő példaprogramban is benne van 22.6 fejezet végén.

Igenigen, de most a STOP kiadasa a kerdeses. Multimaster kornyezetben siman lehet az hogy a START kiadasra varni kell (es akkor valoban TWCR[TWINT]-tet kell neznunk, ahogy irod), de mi van a STOP-pal? A STOP-ot ugye csak akkor adhatod ki hogyha korabban a/ master akartal lenni b/ egyszer sem (se cimzesnel, se data transmitnal) nem vesztetted el az arbitration-t. Oke, ez a feltetel fennall. Kiadjuk a STOP-ot, de mikor adhatjuk ki azutan azt hogy akkor alljunk be az "enable acknowledge" (slave listener) allapotba? 

Ha jol emlekszem, az Atmel azert hivja a sajat I2C implementaciojat TWI-nek, mert par dolgot "elfelejtett" implementalni. Egyik talan pont a multimaster, de mar nem emlekszem pontosan.

Kicsit off, de erdekel, hogy mire hasznalod, es miert pont I2C-n akarsz ket/tobb ATMEGA328P-t osszekotni (meg fene tudja meg milyen slave-eket).

A strange game. The only winning move is not to play. How about a nice game of chess?

Ha jol emlekszem, az Atmel azert hivja a sajat I2C implementaciojat TWI-nek, mert par dolgot "elfelejtett" implementalni. Egyik talan pont a multimaster, de mar nem emlekszem pontosan.

Minden ilyesmit tud az Atmeles I2C implementacio (multimaster, clock sync, clock stretching), szerintem inkabb kopirajt okokbol nem hivja/hivhatja I2C-nek :)

Kicsit off, de erdekel, hogy mire hasznalod, es miert pont I2C-n akarsz ket/tobb ATMEGA328P-t osszekotni (meg fene tudja meg milyen slave-eket).

Nem csak Atmel-AVR van a buliban, van itten ESP32 meg STM32F0xx is - sot, ha minden jol megy, lesz sajat core is, FPGA-ban. A kommunikacio az klasszik half duplex: nincs iranyvaltas akkor mikor valaki megnyeri az arbitrationt: azaz csak MT es SR uzemmodok vannak a folyamatban, MR es ST nincs. Ezert is fontos hogy az MT lezartakor rogton mar "eljen" az SR, ld. eredeti kerdes. Szoval kicsit ugy mintha CAN-t hasznalnank. 

Ilyen esetben nem lenne jobb egy olyan buszt használni, ami eleve nem master-slave felépítésű? Pl. CAN?

Alternatívaként még azzal is meg lehetne próbálkozni, hogy a slave-et a kontroller perifériával kezeled, a mastert pedig GPIO módban? I2C-nél nem vészesen bonyolult a bitbang master :)

Igenigen, CAN-t is hasznalunk :)

Nem, a bitbang-et szeretnenk kerulni. Ha mar megszakitasvezerelt a dolgok egy resze, plusz az STM32F0 oldalon a DMA-n is gondolkodom akkor nem biztos hogy az a jo irany :) Raadasul csak single-master modban egyszeru az, a multi-master clock synchronization mar elegge nehez szoftverbol. 

A master - slave már nem elég PC... ;-)

"Jegyezze fel a vádhoz - utasította Metcalf őrnagy a tizedest, aki tudott gyorsírni. - Tiszteletlenül beszélt a feljebbvalójával, amikor nem pofázott közbe."