цифровая электроника
вычислительная техника
встраиваемые системы

 



Превращаем Arduino UNO в сниффер шины I2C

Автор: Mike(admin) от 1-10-2024, 23:55

Сканирование шины I2C с использованием Arduino в качестве ведущего устройства довольно просто, но регистрация трафика без ведущего или ведомого устройства – нет. В интернете вы можете найти несколько проектов снифферов I2C, но далеко не все они функциональны. Поэтому мы разработаем свой собственный.


Превращаем Arduino UNO в сниффер шины I2C

Чтобы использовать его, вам нужно подключить SDA и SCL к A4 и A5, как если бы это был ведущий или ведомый узел шины I2C.


Превращаем Arduino UNO в сниффер шины I2C

Проект отлично работает даже с тактовой частотой 400 кГц (как гласит теорема Найквиста-Шеннона, вам всегда нужно делать выборку как минимум с удвоенной частотой сигнала, который вы хотите проанализировать). Двум операторам ассемблера требуется всего 1 + 2 цикла. При F_CPU = 16 МГц он дает частоту выборки 5,33 МГц, что более чем достаточно. Код программы сниффера на основе Arduino следующий:



#define ASM

const byte SDA_mask = 0x10; /* A4 */
const byte SCL_mask = 0x20; /* A5 */
const byte bothHigh = SDA_mask + SCL_mask;
char wr[] = "WR";

void setup() {
  Serial.begin(115200);
  Serial.println(__FILE__);
  Serial.println("SCL SDA");
}

void loop() {
  while (PINC == B00110000);
  const int N = 500 - 1;
  byte b[N];
  cli();
#ifdef ASM
  asm volatile(
    ".rept %[count]\n"  
    "in r0, %[pin]\n"   
    "st Z+, r0\n"       
    ".endr"
    ::      "z" (b), 
    [count] "i" (sizeof b),
    [pin]   "I" (_SFR_IO_ADDR(PINC))
    : "r0"
  );
#else
  for (int i = 0; i < N; i++) b[i] = PINC;
#endif
  sei();
  Serial.print("0.1 0.1"); 
  byte sclPrev = 0;
  byte sclCnt = 0;
  byte adr = 0;
  byte data = 0;
  for (int i = 0; i < N; i++) {
    byte scl = bitRead(b[i], 5);
    byte sda = bitRead(b[i], 4);
    char out[] = "2 0";
    if (scl) out[0]++;
    if (sda) out[2]++;
    Serial.println(out);

    if (scl > sclPrev) {
      sclCnt++;
      switch (sclCnt) {
        case 2 ... 9: adr = adr * 2 + sda; break;
        case 11 ... 18: data = data * 2 + sda; break;
      }
    }
    sclPrev = scl;
  }
  Serial.print("SCL SDA__adr=0x");
  if (adr < 32) Serial.print(0);
  Serial.print(adr / 2, HEX);
  Serial.print("_");
  Serial.print(wr[adr & 1]);
  Serial.print("_data=");
  Serial.println(data);
}

На самом деле, вам придется использовать Serial Plotter "старой" IDE, чтобы увидеть результаты. Декодированные значения будут отображены в заголовке плоттера.


Превращаем Arduino UNO в сниффер шины I2C



© digitrode.ru


Теги: Arduino




Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий