Comments 49
https://ru.aliexpress.com/item/1PCS-USB-Logic-Analyzer-Device-Set-USB-Cable-24MHz-8CH-24MHz-for-ARM-FPGA-M100/32783151577.html
и будет тебе счастье
Счастья не будет… одно только разочарование. Всё это сказки сплошные, кроме того что оно МОЖЕТ захватывать.
Но из-за маленького размера буфера, которого едва хватает на один фрейм USB малейшая задержка или непонятный чипсет, и анализатор становится бесполезным и его хочется сначала об стенку потом в мусорку.
И во вторых, никакой наглядности процесса — пока не закончится захват ничего он на экране не покажет… а как понять когда хватит? Или вообще когда начинать захват? По понятным причинам, визуализировать захваченное сразу же в реальном времени нельзя — чуть что, контроллер USB задумался и захват сорван. Мышку пошевелил на том же контроллере где и лог.анализатор и привет — захват сорван.
Если же вы хотите USB (2.0/3.0 и прочее) — берите лог анализатор по круче да подороже, кто мешает?
На гиктаймс 99% аудитории будет достаточно данного анализатора, а остальные 1% я думаю сами в состоянии понять и выбрать — что им купить в соответствии с их запросами.
А я про сам анализатор, не про протоколы которые он может разобрать. Короче хлам то всё, работает только если не дышать и знать точно когда можно захват делать и надеяться на удачу что требуемый кусок попал в выделенный заранее временной интервал.
А в разрыв как-то не совсем правильно. Лучше уж тогда использовать процессор помощнее, типа STM32. Ну, или подключить параллельно на шину сдвиговые регистры. Вход на SDA, строб на SCL, а 8 выходов целиком на порт контроллера, и можно быстро забирать байты прямо из регистра IDR порта.
А потом запрогать его ещё для чего-нибудь.
Но ОК, варианты явно лучше, для всего есть свои задачи, всё лучше чем над ардуиной издеваться.
А в целом — ну как можно на маломощном МК с подключенным UART на 115200 бод поймать хоть что-то внятное идущее на гораздо более высоких скоростях. Как помощь при обучении или простенькие одиночные посылки поймать-послать — вполне. Но для чего-то более серьезного такие устройства не подходят. Ну и работа в консоли — на любителя
И осциллографы, которые декодируют кучу протоколов.
существуют логические анализаторы, которые не только захватят, но и разберут и красиво покажут весь обмен данными по любым более-менее популярным протоколамsigrok: разбирает кучу протоколов.
FOSS.
В качестве аппаратных интерфейсов поддерживает в том числе копеешные железяки из коммента выше.
{
cli();
…
uart_send_char(data);
…
sei();
Потеряете все события на входе внешнего прерывания кроме первого, пока не выполнится uart_send_char(data). А это довольно долго. Вложенные прерывания запрещать не надо и правильная uart_send_char(data) тоже должна работать по прерываниям.
Думаю, что надо было просто раскурить как следует мануал на блок TWI, а не возиться с «bit-bang'ом навыворот».
115200кБод это 57,6кГц же.
Ну как-же так? 115.2 кГц… вот прям щас на осциллографе посмотрел.
Если хочется писать большое количество данных, то цепляем гиг ОЗУ (у альтеры есть готовое IP ядро для новичков) и пишем в них очень и очень долго. Можно сразу и в юарт сливать. Использование FIFO в ОЗУ позволит и записать много данных и не потерять ничего.
В идеале, конечно, чтобы декодеры протоколов были тоже аппаратные. Но про такое слышал только в контексте MegaZoom IV ASIC для Keysight осциллографов…
Это же не АЦП данные, по одному битику в спартан xc6slx9 можно полмиллиона отсчётов запихать, т.е. секунду обмена.
Во вторых я пока мало знаком с i2c, только bme280 завёл на оранжпай, так, диванные рассуждения.
В третьих я слышал про более быстрые уарты, х.з. как с поддержкой скоростей компами, но на плисе можно любую скорость реализовать.
Поэтому не нужно в них писать cli(), sei();
Вообще идея вставать в разрыв не самая удачная, т.к. I2C поддерживает мультимастеринг на шине, и в неудачном случае можно с удивлением обнаружить транзакции приходящие с обеих сторон ;)
Собственно, ни разу не видел анализаторов, которые требуют делать разрыв
абсолютно верно — на атмегах нельзя i2c аппаратно использовать для мониторинга/сниффинга. они начинают влезать в разговор. и «старый мастер» может не понять такой шутки и обидеться. (у меня так и получалось изредка, шина вставала)
тиньки могут, там twi урезан, но мне не подошли.
для сниффинга скорости атмеги не хватает, если шина загружена. по-хорошему только вариант сбор в память — выгрузка всего с потерей данных во время выгрузки.
итого — бардак ) потом уже с из китайчины дешевый логический анализатор пришел — просто день и ночь ))))
а с non-intrusive мониторингом в итоге: вложенные прерывания и отлов только конкретного события. отлично работает. думаю так же и сниффить можно пробовать.
//i2c part
#define SCL_PIN PD2 //INT0
#define SDA_PIN PD3 //INT1
#define TRIGGER_EVENT 1
volatile uint8_t i2c_trigger = 0;
register volatile uint8_t bits_to_read asm("r5");
register volatile uint8_t bits_value asm("r6");
register volatile uint8_t bytes_to_read asm("r7");
register volatile uint8_t current_bits asm("r8");
#define BUFFER_SIZE 3 // maximum size of buffer for message: i had to sniff only a packet of 3 bytes: address+data+data
volatile uint8_t i2c_cmd_buffer[BUFFER_SIZE];
void setup() {
i2c_cmd_buffer[0] = 0;
i2c_cmd_buffer[1] = 0;
i2c_cmd_buffer[2] = 0;
// sda/scl
DDRD &= ~(_BV(DDD2)|_BV(DDD3)); // PD2 and PD3 pins as INPUT
EICRA |= _BV(ISC00)|_BV(ISC01)|_BV(ISC10); // set INT0 to trigger on RISING
// set INT1 to trigger on ANY logic change
EIMSK |= _BV(INT1); // only enable INT1. INT0 (SCL) won't be enabled until we see a START
sei(); // turn on interrupts
}
void loop() {
if (i2c_trigger) {
cli();
//do something here.
//we have just noticed specific message on i2c bus
i2c_trigger = 0;
sei();
}
}
ISR (INT0_vect) { // SCL interrupt code here. SCL RISE. Read bits from SDA
if (bits_to_read-- > 0 ) {
bits_value <<= 1;
if(PIND & _BV(PD3)) {
bits_value |= 1;
}
} else { //ack/nack
if (bytes_to_read < BUFFER_SIZE) {
i2c_cmd_buffer[bytes_to_read++] = bits_value;
}
bits_to_read = 8;
bits_value = 0;
}
}
ISR (INT1_vect) { // SDA interrupt code here. SDA CHANGE
if (!(PIND & _BV(PD2)))
return; // clk is low
if (PIND & _BV(PD3)) {
// SDA is rising. its a STOP condition
// disable interrupt for SCL rising
EIMSK &= ~_BV(INT0);
//stop condition. we've finally got message we was waiting for. set flag.
i2c_trigger = (i2c_cmd_buffer[0] == 0x4e && i2c_cmd_buffer[1] == 0x99) ? TRIGGER_EVENT : 0;
} else {
// SDA is falling. its a START condition
// enable interrupt for SCL rising
EIMSK |= _BV(INT0);
bits_to_read = 8;
bits_value = 0;
bytes_to_read = 0;
}
}
а мониторинг делал в итоге
Примерно то же касается идеи разрыва линии — I2C часто разводится в пределах одной платы, подключение сниффера часто возможно только в одной точке.
uart интерфейсу, который, к слову, работал на максимальной стабильной скорости 38 кбит/с
хм, а тактовая частота кристалла какая? и что за мега? 8,16...?
мк в разрыве не давал побочных задержек?
I2C-сниффер