SPI communication protocol, AVR debugging...

Немедленно нажим на RESET, All!

Дано: 4 контроллера, SPI шина. Нужно организовать обмен сообщениями. Один MCU -- ведущий (видимо, организует опрос в цикле), остальные ведомые. Помимо собственно SPI имеется сигнал выбора конкретного MCU. Хочется организовать поверх SPI что-то вроде "микро RPC", например как описывается в "

formatting link
". Требуется какой-либо протокол обмена позволяющий обнаруживать, не обязательно исправлять, ошибки, восстанавливать синхронизацию после сбоев. Возможные ошибки: искажение битов, сдвиги влево/вправо. Можно считать, что в начале обмена синхронность обеспечивается тем самым сигналом выбора контроллера. Ведущему контроллеру, при приёме информации от ведомого нужно как-то знать передал ли он всю информацию. Нужно как-то минимизировать потери информации при различных сбоях (например, при потере байтовой синхронизации дальнейший приём и передача смысла не имеют). Вариант: после каждого переданного и принятого информационного пакета прекращать и возобновлять обмен для восстановления синхронизации. Использовать экранировку символа \xff, который использовать как признак начала/конца пакета.

Ваше мнение?

Дальше-больше. Хочется вести отладку подчинённых контроллеров через этот же интерфейс... То-есть мне нужен не внутрисхемый отладчик, что обычно используется, а загружаемый в MCU монитор, к которому можно было бы написать собственную интерфейсную часть.

Варианты:

  1. мучаться с патчами к gdb имени Д. Чистякова; 2. дописать самодельный монитор к avrice; 3. "
    formatting link
    "; Склоняюсь к первому варианту. Могут быть другие варианты?
Reply to
Kirill Frolov
Loading thread data ...
Reply to
Vladimir Vassilevsky
Reply to
Vladimir Vassilevsky

Hello, Vladimir Vassilevsky! You wrote in conference fido7.ru.embedded to Kirill Frolov on Thu, 30 Jun 2005 02:07:14

+0400:

VV> Wed Jun 29 2005 13:18, Kirill Frolov wrote to All:

KF>> Дано: 4 контроллера, SPI шина. Hужно организовать обмен KF>> сообщениями. KF>> Один MCU -- ведущий (видимо, организует опрос в цикле), KF>> остальные ведомые.

VV> Как написавший много подобных протоколов, имею сказать.

VV> 1. Hе пытайтесь работать по SPI в дуплексе. Трахаться с

Почему??? Ведь если что-то передаешь, то одновременно и принимаешь (и наоборот). Чем проще принятое выбрасывать?

VV> отладкой - оно того не стоит. Либо сообщение туда, либо VV> сообщение сюда, но не одновременно.

Я делал именно что одновременно, по прерываниям, с ключевым байтом в начале и контрольной суммой в конце. Для остальной программы это выглядело как набор переменных одного контроллера в другом.

VV> 3. От слейвов к мастеру нужно один общий сигнал для хендшейка/квитирования.

Зачем?

VV> От мастера к каждому из слейвов нужно СS.

И его я на вход внешнего прерывания заводил.

VV> Дальше все пишется элементарно на машинах состояния.

Дальше - именно так.

dima

formatting link

Reply to
Dmitry Orlov
Reply to
Vladimir Vassilevsky

Hello, Vladimir Vassilevsky! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Thu, 30 Jun 2005 18:58:19

+0400:

VV>>> 1. Hе пытайтесь работать по SPI в дуплексе. Трахаться с

DO>> Почему??? Ведь если что-то передаешь, то одновременно и DO>> принимаешь (и наоборот). Чем проще принятое выбрасывать?

VV> Мастер начинает обмен в произвольный момент. При этом он не VV> знает, успел ли слейв записать в SPI. Приходится придумывать

Что значит успел или не успел? Буфер его все равно передается, прерывание по его заполнению все равно возникает.

VV> затейливое квитирование туда-сюда с дополнительными линиями VV> и очень хорошо все продумывать на предмет возможных VV> дедлоков.

Что-то у меня все работало вполне устойчиво с одной линией от мастера к слейву (приходила на RB0 пика). Разумеется я пробовал создавать ему искусственно ненормальные условия. Да там и естественные такие, что мало не покажется. Мастер от слева был оптронами развязан и по обе стороны шумящие smps'ы на киловатт с гаком.

DO>> Я делал именно что одновременно, по прерываниям, с ключевым DO>> байтом в начале и контрольной суммой в конце. Для остальной DO>> программы это выглядело как набор переменных одного DO>> контроллера в другом.

VV> Примитивно.

Это положительная характеристика.

VV> Stall любого из контроллеров, потерянный байт или где-то поменялись времена - VV> все повисло до ресета.

Отнюдь. Кстати, даже контрольной суммы, посмотрев таки исходники, я не делал, впрочем добавляется легко. По прерыванию от rb0 слейв переинициализирует SPI. Мастер делает тоже самое по прерыванию от таймера, где инициализируется передача. В принципе это можно и не по прерыванию делать, мне просто было в том устройстве так удобнее. Где ты видишь место для затыка? Ну приедет один битый пакет, отфильтруется по несовпадению контрольной суммы или просто признака конца/начала, собственно контроль целостности данных прямого отношения к их квитировнию не имеет и зависит от того на сколько эти данные критичны. Важно, что никакого затыка при разумном соотношении нормально и ненормально принятых бит быть не может. Машина состояния аппаратно обновляется при обмене каждого пакета (вместе с железом spi).

VV>>> 3. От слейвов к мастеру нужно один общий сигнал для VV>>> хендшейка/квитирования. DO>> Зачем?

VV> Чтобы мастер знал, что слейвы готовы к обмену по SPI.

Как они могут быть неготовы, если обмен делается аппаратно и вызывает прерывание? То есть теоретически я себе такое представить могу, но такую ситуацию считать общим явлением я бы не стал. Но даже если и так, зачем физически дуплексному обмену искусственно отрезать дуплексность минимум вдвое снижая пропускную способность, да еще и в условиях, когда на такую мелочь, как пересылка данных в буфер по прерыванию может не быть времени?

dima

formatting link

Reply to
Dmitry Orlov

Hello, Vladimir Vassilevsky! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Thu, 30 Jun 2005 20:23:21

+0400:

VV> Thu Jun 30 2005 20:58, Dmitry Orlov wrote to Vladimir VV> Vassilevsky:

VV>>>>> 3. От слейвов к мастеру нужно один общий сигнал для VV>>>>> хендшейка/квитирования. DO>>>> Зачем? VV>>> Чтобы мастер знал, что слейвы готовы к обмену по SPI.

DO>> Как они могут быть неготовы, если обмен делается аппаратно и DO>> вызывает прерывание?

VV> Да очень просто: мастер уже начал следующий трансфер, а слейв VV> еще не успел отработать SPI.

Постой, мы об одном и том же spi говорим? Который суть два сдвиговых регистра ?

VV> Или слейву дали команду что-то сделать и вернуть результат, а результат еще VV> не готов.

Вернется при следующем обмене, а при этом - результат предыдущей команды.

VV> Все дополнительно усложняется небуфферизированностью передачи VV> по SPI и невозможностью посмотреть, в каком состоянии VV> находится приемник (идет трансфер или не идет).

Как это небуферезированностью? Есть регистр сдвига, и есть буферный регистр. А идет ли трансфер? На то флаг есть.

DO>> Hо даже если и так, зачем физически дуплексному обмену DO>> искусственно отрезать дуплексность минимум вдвое снижая DO>> пропускную способность,

VV> Пропускная способность для SPI - не проблема. Дуплексность VV> сильно усложняет логику.

Я этого как-то не заметил. Прочитал буфер, записал буфер:

/* Slave */ if (INTF == 1) /* external interrupt (SPI SC) */ { INTF = 0; /* Clear external interrupt flag */ /*-------------- Init SPI ------------------------*/ SSPEN = 0; SSPSTAT = 0; SSPCON = 0B00100101; PEIE = 1; SSPIE = 1; /*------------------------------------------------*/ SSPBUF = 0xA5; /* Send signature */ sscntr = 0; } if (SSPIF == 1) { SSPIF = 0; if (sscntr == 0) { if (SSPBUF != 0x5A) sscntr = 255; /* Receive and check signature */ else SSPBUF = Vin; /* Send Vin (Vscell) */ } else if (sscntr == 1) { Vout = SSPBUF; /* Receive Vout (DAVin) */ SSPBUF = DDterm; /* Send DD temperature */ } else if (sscntr == 2) { Iout = SSPBUF; /* Receive Iout (DAIin) */ SSPBUF = DDstate; /* Send DDstate */ } else if (sscntr == 3) { DAstate = SSPBUF; /* Receive DAstate */ SSPBUF = DAcmd; /* Send DAcmd */ } else if (sscntr == 4) { DAterm = SSPBUF; /* Receive DAterm */ SSPBUF = DDalarm; /* Send DDalarm */ } else if (sscntr == 5) { DAalarm = SSPBUF; /* Receive DAalarm */ SSPBUF = 0; /* Just send */ } else if (sscntr == 6) { Vmains = SSPBUF; /* Receive Vmains */ SSPBUF = 0; /* Just send */ } else if (sscntr == 7) { Imains = SSPBUF; /* Receive Vmains */ SSPBUF = 0; /* Just send */ ss_timeout = 0; /* Clear SPI timeout if OK */ } sscntr++; }

/* Master */

if (int_cntr == 64) scs = 1; /* Set SPI chip select */ if (int_cntr == 66) { tx = 0; _10msc++; SSPBUF = 0x5A; /* Send signature */ sscntr = 0; /* Clear ss counter */ sinwav = 0; }

/* SPI */ if (SSPIF ==1) { SSPIF = 0; /* Clear SPI interrupt flag */ if (sscntr == 0) { if (SSPBUF != 0xA5U) /* Check signature */ { ss_ok = 0; sscntr = 255U; scs = 0; } else SSPBUF = Vin; /* Send Vin (DDVout) */ } else if (sscntr == 1) { Vscell = SSPBUF; /* Receive Vscell (DDVin) */ SSPBUF = Iin; /* Send Iin (DDIout) */ } else if (sscntr == 2) { DDterm = SSPBUF; /* Receive DDterm */ SSPBUF = DAstate; /* Send DAstate */ } else if (sscntr == 3) { DDstate = SSPBUF; /* Receive DDstate */ SSPBUF = ad_res[adTerm]; /* Send DAterm */ } else if (sscntr == 4) { DAcmd = SSPBUF; /* Receive DAcmd */ SSPBUF = DAalarm; /* Send DAalarm */ } else if (sscntr == 5) { DDalarm = SSPBUF; /* Receive DDalarm */ SSPBUF = Vout; /* Send Vout */ } else if (sscntr == 6) { SSPBUF = Iout; /* Send Iout */ if (ss_ok < 255U) ss_ok++; scs = 0; /* Clear SPI chip select */ } sscntr++; /* increment ss counter */ }

dima

formatting link

Reply to
Dmitry Orlov
Reply to
Vladimir Vassilevsky
Reply to
Vladimir Vassilevsky

Hello, Vladimir Vassilevsky! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Fri, 01 Jul 2005 19:04:21

+0400:

VV>>>>>>> 3. От слейвов к мастеру нужно один общий сигнал для VV>>>>>>> хендшейка/квитирования. VV>>>>> Чтобы мастер знал, что слейвы готовы к обмену по SPI. DO>>>> Как они могут быть неготовы, если обмен делается аппаратно DO>>>> и вызывает прерывание? VV>>> Да очень просто: мастер уже начал следующий трансфер, а VV>>> слейв еще не успел отработать SPI. DO>> Постой, мы об одном и том же spi говорим? Который суть два DO>> сдвиговых регистра ?

VV> Hет, о разных :) Ты говоришь о пикоманском SPI, а я об VV> AVRовском, BlackFinовском и моторольском.

Я дело имел только с микрочиповским, неужели у остальных оно чем-то принципиально хуже?

VV>>> Все дополнительно усложняется небуфферизированностью VV>>> передачи по SPI и невозможностью посмотреть, в каком VV>>> состоянии находится приемник (идет трансфер или не идет).

DO>> Как это небуферезированностью? Есть регистр сдвига, и есть DO>> буферный регистр.

VV> Хорошо если есть. А если пишется/читается прямо из сдвигалки?

А что, так кто-то делает? У AVR точно есть, уверен и у остальных (лень в даташиты лазить) тоже.

DO>> А идет ли трансфер? Hа то флаг есть.

VV> Флаг есть что трансфер закончен. Hет флага, что трансфер в VV> процессе.

Ну с момента записи в буфер оно в процессе, пока флаг не покажет обратного...

VV>>> Дуплексность сильно усложняет логику. DO>> Я этого как-то не заметил. Прочитал буфер, записал буфер:

VV> Как ты гарантируешь что слейв успевает за мастером?

А как он может не успевать, если он тактируется мастером? Не успевать прочитать байт из буфера и зарядить туда новый? Успевает, как факт. Всегда.

VV> Можно, конечно, сделать пакетный протокол с подтверждениями VV> в обе стороны, но мне больше нравится делать на SPI протокол

Можно, как я показал, и не делать. Никаких зависаний, клинчей и т. п. После сбоев все само восстанавливается. Ноги и развязанные в моем случае линии экономятся.

VV> а-ля I2C. Для этого нужен один общий сигнал квитирования от слейвов к VV> мастеру.

В каких-то частных случаях может быть. Но может и не быть.

dima

formatting link

Reply to
Dmitry Orlov

Hello, Vladimir Vassilevsky! You wrote in conference fido7.ru.embedded to Dmitry Orlov on Fri, 01 Jul 2005 22:01:22

+0400:

VV>>> Флаг есть что трансфер закончен. Hет флага, что трансфер в VV>>> процессе. DO>> Hу с момента записи в буфер оно в процессе, пока флаг не DO>> покажет обратного...

VV> Это на мастере. Hа слейве неизвестно.

Гм. Почему неизвестно?

VV>>> Как ты гарантируешь что слейв успевает за мастером? DO>> А как он может не успевать, если он тактируется мастером? Hе DO>> успевать прочитать байт из буфера и зарядить туда новый? DO>> Успевает, как факт. Всегда.

VV> Скорость SPI - мегабайты в секунду. Cлейв запросто может не VV> успевать.

Значит, если слейв не успевает, надо передавать так, чтобы успевал. В рамках одного устройства все делается...

dima

formatting link

Reply to
Dmitry Orlov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.