RTV forum PL | NewsGroups PL

I2C na AVR: Jak programowo przydzielić adresy dla wielu modułów?

I2C i automatyczne przydzielanie adresu

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - I2C na AVR: Jak programowo przydzielić adresy dla wielu modułów?

Dariusz Zolna
Guest

Mon Mar 17, 2008 3:57 pm   



Mam pewien układ, złożony z modułu głównego i wielu mniejszych
komunikujących się z głównym przez I2C (wszystko na AVR). Jako że układ
z założenia ma mieć możliwość podpinania kolejnych modułów (także kilku
tego samego typu), istnieje potrzeba wyboru adresu I2C dla każdego z
nich. Najprościej byłoby użyć np zadajnika kodu HEX i kilku portów
procka na każdym module. Problemem jednak jest:
- brak wolnych pinów
- marnowanie wolnych adresów (trzeba by np rezerwować pulę adresów na
każdy rodzaj modułu i mimo że np byłby taki jeden w systemie, zajęte
byłoby 16 adresów)
Macie jakieś pomysły, żeby nadać te adresy programowo? Na razie chodzi
mi jakaś niejasna koncepcja z wykrywaniem urządzeń o adresie np 0 (czyli
nieprzydzielonym, od którego startowałyby wszystkie Slave). Jeśli Master
wykryłby urządzenie o takim adresie, wysyłałby do niego nowy adres,
jeśli nie, to kończyłby enumerację. O ile pamiętam, to w przypadku
konfliktu adresów, dane przesyłane są tylko do jednego ze Slave, więc
mogłoby zadziałać, ale poprawcie mnie jeśli się mylę, lub są w tym
jakieś haczyki.

Dariusz Żołna

Wojciech Piechowski
Guest

Mon Mar 17, 2008 4:41 pm   



Dariusz Zolna pisze:
Quote:
Mam pewien układ, złożony z modułu głównego i wielu mniejszych
komunikujących się z głównym przez I2C (wszystko na AVR). Jako że układ
z założenia ma mieć możliwość podpinania kolejnych modułów (także kilku
tego samego typu), istnieje potrzeba wyboru adresu I2C dla każdego z
nich. Najprościej byłoby użyć np zadajnika kodu HEX i kilku portów
procka na każdym module. Problemem jednak jest:
- brak wolnych pinów
- marnowanie wolnych adresów (trzeba by np rezerwować pulę adresów na
każdy rodzaj modułu i mimo że np byłby taki jeden w systemie, zajęte
byłoby 16 adresów)
Macie jakieś pomysły, żeby nadać te adresy programowo? Na razie chodzi
mi jakaś niejasna koncepcja z wykrywaniem urządzeń o adresie np 0 (czyli
nieprzydzielonym, od którego startowałyby wszystkie Slave). Jeśli Master
wykryłby urządzenie o takim adresie, wysyłałby do niego nowy adres,
jeśli nie, to kończyłby enumerację. O ile pamiętam, to w przypadku
konfliktu adresów, dane przesyłane są tylko do jednego ze Slave, więc
mogłoby zadziałać, ale poprawcie mnie jeśli się mylę, lub są w tym
jakieś haczyki.

Dariusz Żołna

Jak będzie konflikt adresów to dane otrzymują wszyscy pod tym adresem.

wersja A: wpinać tylko po jednym nieprzydzielonym module jednocześnie,
to kolizji nie będzie. Jak master już przydzieli nowemu adres, to można
kolejnego nowego dołożyć.

wersja B: każde urządzenie niezainicjowane losuje se długą sekwencję
bitów (np. tworząc ją z najmniejszego bitu kolejnych odczytów wiszącej
lub zaszumionej nogi ADC). Master robi odczyt tej sekwencji z adresu 0,
czyli wszyscy potencjalni niezainicjowani się chwalą swoją sekwencją.
Sekwencje są losowe, więc najprawdopodobniej się różnią, przy
odpowiedniej długości sekwencji można to uznać za aksjomat. No i wszyscy
jednocześnie wystawiają te swoje bity, prędzej czy później będzie
konflikt - jedni chcą zera, inni jedynkę. Ci z jedynką przegrają,
dowiedzą się że nie są jedynymi i odpadają z tego okrążenia (arbitration
lost w atmega). Ci z zerami idą dalej po kolejnych bitach, na każdym
kolejnym konflikcie ktoś odpada. Po wysłaniu wszystkich do mety powinien
dobiec tylko jeden, chyba że wylosowane kody się powtarzają. A wtedy
master wysyła do wszystkich niezaicjowanych: "ty, który do końca
wytrwałeś, od teraz nazywasz się xxx". I kolejna runda, aż się skończą
niezainicjowani.

wersja C: wpisać adres do EEPROMa modułu przed wpięciem do systemu.

W

J.F.
Guest

Mon Mar 17, 2008 4:52 pm   



On Mon, 17 Mar 2008 15:57:18 +0100, Dariusz Zolna wrote:
Quote:
Macie jakieś pomysły, żeby nadać te adresy programowo? Na razie chodzi
mi jakaś niejasna koncepcja z wykrywaniem urządzeń o adresie np 0 (czyli
nieprzydzielonym, od którego startowałyby wszystkie Slave).

Zobacz jak dzialalo PnP na ISA.
Mimo wszystko wolalbym chyba na przelaczniku ..

Wypadaloby jeszcze wprowadzic indywidualny numer w kazdym z modulow ..

J.

Konop
Guest

Mon Mar 17, 2008 7:02 pm   



Dariusz Zolna pisze:
Quote:
Mam pewien układ, złożony z modułu głównego i wielu mniejszych
komunikujących się z głównym przez I2C (wszystko na AVR). Jako że układ
z założenia ma mieć możliwość podpinania kolejnych modułów (także kilku
tego samego typu), istnieje potrzeba wyboru adresu I2C dla każdego z
nich. Najprościej byłoby użyć np zadajnika kodu HEX i kilku portów
procka na każdym module. Problemem jednak jest:
- brak wolnych pinów
- marnowanie wolnych adresów (trzeba by np rezerwować pulę adresów na
każdy rodzaj modułu i mimo że np byłby taki jeden w systemie, zajęte
byłoby 16 adresów)
Macie jakieś pomysły, żeby nadać te adresy programowo? Na razie chodzi
mi jakaś niejasna koncepcja z wykrywaniem urządzeń o adresie np 0 (czyli
nieprzydzielonym, od którego startowałyby wszystkie Slave). Jeśli Master
wykryłby urządzenie o takim adresie, wysyłałby do niego nowy adres,
jeśli nie, to kończyłby enumerację. O ile pamiętam, to w przypadku
konfliktu adresów, dane przesyłane są tylko do jednego ze Slave, więc
mogłoby zadziałać, ale poprawcie mnie jeśli się mylę, lub są w tym
jakieś haczyki.

Dariusz Żołna

Wiesz, jak działa arbitraż w I2C?? jeśli mamy 2 urządzenia o tym samym
adresie i zaczną one nadawać jednocześnie, to co się stanie?? Otóż układ
nadając cały czas sprawdza stan linii SDA. Urządzenie, jak nadaje "1", a
na linii ma "0", to wie, że jest konflikt - i się wyłącza Smile... no i to
będzie podstawa Smile... musisz każdemu urządzeniu nadać numer seryjny -
niepowtarzalny!! Z tym, że może on być dowolnie długi Smile... teraz tak,
host wysyła na domyślny adres komendę "przedstaw się" (tzn. podaj numer
seryjny). Teraz wszyscy zaczynają nadawać swój numer seryjny, ale
wszyscy (poza jednym) odpadają. Zostaje ten o najmniejszym numerze
seryjnym. Dlaczego?? Patrz zasada arbitrażu Smile... każdy nadaje swoją
sewkencję, jak chce nadać "1" i widzi, że jest "0" (wymuszone przez inne
urządzenie) to się wyłącza... i tyle... po wysłaniu numeru seryjnego
host nadaje urządzeniu adres i powtarza całą czynność do momentu, w
którym na komendę "przedstaw się" pod adresem domyślnym nic nie odpowie
(czyli odbierze same "1" Smile..
Zalety tej metody są takie:
-sposób "arbitrażu" jest zgodny z I2C
-możesz sobie wymyślić dowolnie długi kod seryjny i w ten sposób
obsługiwać dowolną ilość urządzeń (tzn. nie naraz Wink)
-pomimo długiego kodu ustalenie adresu nie trwa długo
-adres może być krótki pomimo długiego kodu seryjnego
-możesz ustalić u "hosta" na stałe pewne adresy dla pewnych urządzeń
(może być tu przydatna funkcja alternatywnego "wzywania" układów - nie
przez adres a przez numer seryjny)

Inna metoda, jaka mi do głowy przychodzi to taka, że urządzenie
SAMODZIELNIE zmieni swój adres gdy wykryje konflikt... ale nie wiem, czy
da się to zrealizować w jakiś sensowny sposób - poza tym, host nie
wiedziałby o tym... a chyba po to nadajesz adresy, żeby host mógłby te
urządzenia rozróżnić Wink....

Pozdrawiam
Konop

T.M.F.
Guest

Mon Mar 17, 2008 7:11 pm   



Quote:
Macie jakieś pomysły, żeby nadać te adresy programowo? Na razie chodzi
mi jakaś niejasna koncepcja z wykrywaniem urządzeń o adresie np 0 (czyli
nieprzydzielonym, od którego startowałyby wszystkie Slave). Jeśli Master
wykryłby urządzenie o takim adresie, wysyłałby do niego nowy adres,
jeśli nie, to kończyłby enumerację. O ile pamiętam, to w przypadku
konfliktu adresów, dane przesyłane są tylko do jednego ze Slave, więc
mogłoby zadziałać, ale poprawcie mnie jeśli się mylę, lub są w tym
jakieś haczyki.

Tak ci to nie zadziala, bo w przypadku konfliktu jak ci napisano
odpowiedza wszystkie urzadzenia.
Ale to nie problem. Mozesz to zrobic na kilka sposobow jak podano, ze
swojej strony dorzucilbym kolejny - rozwiazywanie konfliktow tak jak w
sieci ethernet, masz konflikt pomiedzy dwoma urzadzeniami o tym samym
adresie (zero w tym przypadku), kazde z urzadzen w przypadku
stwierdzenia konfliktu losuje sobie czas nieaktywnosci w ktorym nie
odpowiada na zapytania. Poniewaz jest nieprawdopodobne, zeby za kazdym
razem dla wszystkich urzadzen ten czas byl identyczny wiec w ten sposob
pojedynczo jestes w stanie inicjalizowac urzadzenia.

--
Inteligentny dom - http://idom.wizzard.one.pl
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz do projektu.

Dariusz Zolna
Guest

Tue Mar 18, 2008 9:16 pm   



T.M.F. pisze:
Quote:
Tak ci to nie zadziala, bo w przypadku konfliktu jak ci napisano
odpowiedza wszystkie urzadzenia.
Ale to nie problem. Mozesz to zrobic na kilka sposobow jak podano, ze
swojej strony dorzucilbym kolejny - rozwiazywanie konfliktow tak jak w
sieci ethernet, masz konflikt pomiedzy dwoma urzadzeniami o tym samym
adresie (zero w tym przypadku), kazde z urzadzen w przypadku
stwierdzenia konfliktu losuje sobie czas nieaktywnosci w ktorym nie
odpowiada na zapytania. Poniewaz jest nieprawdopodobne, zeby za kazdym
razem dla wszystkich urzadzen ten czas byl identyczny wiec w ten sposob
pojedynczo jestes w stanie inicjalizowac urzadzenia.


Dzięki! Ta metoda wygląda na najłatwiejszą w realizacji na AVR. Z
arbitrażem jaki podawano mi w innych postach mogą być pewne problemy
przy korzystaniu ze sprzętowego interfejsu.

Pozdrawiam,
Dariusz Żołna

Dariusz Zolna
Guest

Tue Mar 18, 2008 9:25 pm   



Wojciech Piechowski pisze:
Quote:
Dariusz Zolna pisze:
Jak będzie konflikt adresów to dane otrzymują wszyscy pod tym adresem.

Tak, masz rację.


Quote:
wersja A: wpinać tylko po jednym nieprzydzielonym module jednocześnie,
to kolizji nie będzie. Jak master już przydzieli nowemu adres, to można
kolejnego nowego dołożyć.

Ale trzeba dorzucić dodatkową linię albo odcinać zasilanie, co też
komplikuje układ.


Quote:
wersja B: każde urządzenie niezainicjowane losuje se długą sekwencję
bitów (np. tworząc ją z najmniejszego bitu kolejnych odczytów wiszącej
lub zaszumionej nogi ADC). Master robi odczyt tej sekwencji z adresu 0,
czyli wszyscy potencjalni niezainicjowani się chwalą swoją sekwencją.
Sekwencje są losowe, więc najprawdopodobniej się różnią, przy
odpowiedniej długości sekwencji można to uznać za aksjomat. No i wszyscy
jednocześnie wystawiają te swoje bity, prędzej czy później będzie
konflikt - jedni chcą zera, inni jedynkę. Ci z jedynką przegrają,
dowiedzą się że nie są jedynymi i odpadają z tego okrążenia (arbitration
lost w atmega). Ci z zerami idą dalej po kolejnych bitach, na każdym
kolejnym konflikcie ktoś odpada. Po wysłaniu wszystkich do mety powinien
dobiec tylko jeden, chyba że wylosowane kody się powtarzają. A wtedy
master wysyła do wszystkich niezaicjowanych: "ty, który do końca
wytrwałeś, od teraz nazywasz się xxx". I kolejna runda, aż się skończą
niezainicjowani.

I to w sumie jest zgodne ze standardem (dzięki słowu kluczowemu
"arbitraż" doszukałem się stosownych dokumentów), jednak mam pewne obawy
co do implementacji tej metody przy użyciu sprzętowego interfejsu w AVR.


Quote:
wersja C: wpisać adres do EEPROMa modułu przed wpięciem do systemu.

To też jest jakieś wyjście, bo i tak każdy procek musi być zaprogramowany.
Skorzystam jednak z podpowiedzi kolegi T.M.F.

Pozdrawiam,
Dariusz Żołna

Dariusz Zolna
Guest

Tue Mar 18, 2008 9:27 pm   



J.F. pisze:
Quote:
Zobacz jak dzialalo PnP na ISA.
Mimo wszystko wolalbym chyba na przelaczniku ..

Kolega T.M.F podsunął już ciekawy pomysł.

Quote:
Wypadaloby jeszcze wprowadzic indywidualny numer w kazdym z modulow ..

Owszem, będzie taki, niezależnie od tego jak problem rozwiążę.

Pozdrawiam,
Dariusz Żołna

Dariusz Zolna
Guest

Tue Mar 18, 2008 9:31 pm   



Konop pisze:
Quote:
Wiesz, jak działa arbitraż w I2C?? [...]

Teraz już wiem :)


Quote:
Zalety tej metody są takie:
-sposób "arbitrażu" jest zgodny z I2C
-możesz sobie wymyślić dowolnie długi kod seryjny i w ten sposób
obsługiwać dowolną ilość urządzeń (tzn. nie naraz Wink)
-pomimo długiego kodu ustalenie adresu nie trwa długo
-adres może być krótki pomimo długiego kodu seryjnego
-możesz ustalić u "hosta" na stałe pewne adresy dla pewnych urządzeń
(może być tu przydatna funkcja alternatywnego "wzywania" układów - nie
przez adres a przez numer seryjny)

Wszystko się zgadza, tylko nie wiem czy uda się zrobić sprzętowo na AVR.


Quote:
Inna metoda, jaka mi do głowy przychodzi to taka, że urządzenie
SAMODZIELNIE zmieni swój adres gdy wykryje konflikt... ale nie wiem, czy
da się to zrealizować w jakiś sensowny sposób - poza tym, host nie
wiedziałby o tym... a chyba po to nadajesz adresy, żeby host mógłby te
urządzenia rozróżnić Wink....

Gdyby tylko Slave potrafił nadać sobie nieprzydzielony adres, to nie ma
problemu, bo brak odpowiedzi od Slave o zadanym adresie wykrywa się
łatwo, więc wystarczy "przelecieć" przez 128 adresów.

Pozdrawiam,
Dariusz Żołna

J.F.
Guest

Wed Mar 19, 2008 7:09 am   



On Tue, 18 Mar 2008 21:27:32 +0100, Dariusz Zolna wrote:
Quote:
J.F. pisze:
Zobacz jak dzialalo PnP na ISA.
Mimo wszystko wolalbym chyba na przelaczniku ..

Kolega T.M.F podsunął już ciekawy pomysł.

Owszem, tylko wymaga "wykrycia kolizji".

Co moze byc dosc trudne .. a w PnP to opanowali.

Quote:
Wypadaloby jeszcze wprowadzic indywidualny numer w kazdym z modulow ..
Owszem, będzie taki, niezależnie od tego jak problem rozwiążę.

Ale to jednak pewne utrudnienie w masowej produkcji ..

J.

elektroda NewsGroups Forum Index - Elektronika Polska - I2C na AVR: Jak programowo przydzielić adresy dla wielu modułów?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map