I2C slave na ATtiny214

Pavel Hudecek edizon na seznam.cz
Pondělí Duben 13 15:19:47 CEST 2020


Tak slave nakonec úspěšně rozchozen. Po předělání na přerušení to skoro fungovalo. Pak pomohlo:

https://www.avrfreaks.net/forum/solved-how-use-attiny-1617-i2c-slave

Zajímavá je tahle část:
If (TWI0.SSTATUS & TWI_DIR_bm) {
            TWI0.SDATA =++nnn;	//Transmit data for Master to read
            TWI0_SCTRLB = TWI_SCMD_RESPONSE_gc;
} else {
            TWI0_SCTRLB = TWI_SCMD_RESPONSE_gc;
            nnn = TWI0.SDATA;	//Receive data written by Master
}
Nevím z čeho plyne to pořadí, kdy pracovat s SDATA a kdy s SCTRLB, ale opačně read nechodí.

Ale nakonec zlobí ještě master: Ten komplet chodí, ale nakonec neudělá stop. U slave mám timeout, tak to zas tak nevadí, ale nelíbí se mi to:-)

Zatím je to jen pro read:

void i2cCom(uint8_t rw, uint8_t dLen) { // =====================
	uint8_t n;
	
	TWI0_MCTRLB=TWI_FLUSH_bm; // flush, ack ano, cmd nic
	cekej(10);
	while(1) {
		TWI0_MSTATUS=TWI_BUSSTATE_IDLE_gc; // prechod unknown-iddle
		cekej(50);
		if ((TWI0_MSTATUS & TWI_BUSSTATE_gm)==TWI_BUSSTATE_IDLE_gc) {PIN_led(1); break;} // vydrzelo iddle?
		PIN_ledTgl;
	}
	do {
		i2cTout=0; // timeout pro i2cWait
		TWI0_MADDR=(I2C_slaveAdr<<1) | (rw & 1); // start+adr+rw
		do {
			test8=TWI0_MSTATUS;
			PIN_led(0); PIN_led(1);
		} while((test8 & TWI_RIF_bm)==0 && i2cWait(1)==0);
		// 1010 0010
		if (test8!=(TWI_RIF_bm|TWI_CLKHOLD_bm|TWI_BUSSTATE_OWNER_gc)) { // err po adr
			print("err adr "); printBin(test8, 8); putchar2(' ');
      printN(i2cTout, 3); putchar2('\n');
			break;
		}
		// adr odeslana, ack prijato, bude read (slave->master)
		for (n=0; n<dLen; n++) {
			testPole[n]=TWI0_MDATA;
			TWI0_MCTRLB=TWI_MCMD_RECVTRANS_gc;
			do {
				test8=TWI0_MSTATUS;
				PIN_led(0); PIN_led(1);
			} while((test8 & TWI_RIF_bm)==0 && i2cWait(n+2)==0);
			
			if (test8!=(TWI_RIF_bm|TWI_CLKHOLD_bm|TWI_BUSSTATE_OWNER_gc)) {// err
				print("err rd B"); putchar2('0'+n); putchar2(' ');
				printBin(test8, 8); putchar2(' ');
				printN(i2cTout, 3); putchar2('\n');
				break;
			}
		}
	} while(0);
	TWI0_MCTRLB=TWI_MCMD_STOP_gc; // stop
}

PH

Od: Pavel Hudecek
Jj, vypadá to jednoduše:-)

Asi jsem se trochu ztratil v ifech a whilech, myslel jsem si, že když od toho nepožaduju nic extra (na master read odeslat 4 B), tak že to bude bez přerušení jednodušší. No není. Teď to předělávám na přerušení a zatím to vypadá kratší a přehlednější.

Vtipný je, že vždycky každýmu říkám, aby používali přerušení, že je to jednodušší:-)

PH

Od: Jan Waclawek
Precital som si tu TWI kapitolu z DS (zaujimave, ze asi 4 strany venuju
vysvetleniu standardu I2C) a mne sa to zda na prvy pohlad vcelku jasne.
Samozrejme viem, ze kde sa diabol schovava... Ale pre istotu som pozrel aj
erratu, a tam vyzera ze polozky suvisiace s TWI su vsetky len pre Master
mod a aj tie su v novsej revizii kremika odstranene.

Co presne Ti nefunguje?


------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20200413/79efb6aa/attachment.html>


Další informace o konferenci Hw-list