Scopul proiectului îl reprezintă monitorizarea comunicaţiei I2C dintre 2 dispozitive pentru a determina eventualele probleme de configurare a acestora. Datele interceptate (adrese, biti de start/stop/paritate) sunt afişate pe o interfaţă seriala.
Monitorizarea comunicatiei I2C se face conectand liniile de date si de clock la ATmega324. Cele doua dispozitive a caror comunicatie este interceptata sunt Arduino Uno care are rolul de master si un modul RTCTiny cu rolul de slave. Pentru a putea intercepta comunicatia am redus viteza de transfer dintre cele doua dispozitive.
Viteza maximă a unei comunicaţii interceptate corect este redusă de frecvenţa la care lucrează uC. Schema de mai jos detaliaza semnalele din timpul unei transmisii I2C.
1.Placă PM (kit de bază)
2.Adaptor USB-UART
3.Cablu USB tip B
4.Fire de legatura si headere pini
Proiectul este implementat ca o masina de stari. Tranzitiile dintr-o stare in alta sunt determinate in cadrul a doua rutine de intrerupere PCINT: o rutina pentru linia de date (portA, pinA6) si o rutina pentru semnalul de clock al transmisiei I2C (portC, pinC6). Un exemplu de tranzitie de la inceputul comunicatiei: trecerea liniei de date din starea HIGH si LOW genereaza o intrerupere pe pinul A6. Daca linia de clock este HIGH si starea automatului indica o conexiune care s-a finalizat, automatul va trece in starea de START, indicand o noua transmisie.
Pentru a activa intreruperile pe porturile A si C am configurat registrul PCICR, iar pentru a monitoriza activitatea doar pe pinii A6 si C6 am folosit registrele PMSK. Ambele rutine modifica o variabila globala care retine starea conexiunii I2C.
volatile connection_state; ISR(PCINT0_vect) { /* Change connection_state accordingly */ } ISR(PCINT2_vect) { /* Change connection_state accordingly */ }
In bucla principala, sunt afisate datele folosind USART, cu un baud rate de 57600.
int main(){ init_usart(); while(1) { switch(connection_state) { usart_transmit(); } } }
Pentru conditiile de start, stop, read/write sunt afisate caracterele 'S', 'P', 'R', 'W'. Restul datelor interceptate sunt stocate intr-un buffer si ulterior transmise pentru a fi afisate in format hexazecimal.
Pentru a reduce viteza de transmisie in cazul comunicatiei interceptate si cum semnalul de ceas este controlat de dispozitivul master (placa de Arduino Uno), am setat prescalerul la valoarea 64, obtinand o frecventa de 600Hz.
Cod sursa: i2c_bus_sniffer.zip
BOTH hardware and software must work!
Proiectul a fost o experienta interesanta si frustranta in acelasi timp. Cu siguranta apreciez mai mult proiectele hardware acum.
http://dangerousprototypes.com/docs/Bus_Pirate
http://www.uchobby.com/index.php/2008/09/09/avr-logic-analyzer/
http://cs.curs.pub.ro/wiki/pm/lab/lab1
http://cs.curs.pub.ro/wiki/pm/lab/lab2
https://www.nxp.com/docs/en/user-guide/UM10204.pdf
https://www.sparkfun.com/datasheets/Components/SMD/ATMega328.pdf
http://cs.curs.pub.ro/wiki/pm/prj2019/astratulat/sniffer?do=export_pdf