Sowa, napewno działa Ci ten kod co zamieściłeś. Możesz wyjaśnić dlaczego stosujesz
*AT91C_TWI_MMR &= ( 0xFF00EFFF | (dev_adr<<16) );
zamiast normalnego wpisania do rejestru MMR? Bo to co robisz, to jest jedynie wyzerowanie niektórych bitów w tym rejestrze. I choć w niektórych przypadkach może to działać, ale generalnie na mój gust, zapis jest błędny. Podobnie masz w przypadku odczytu z TWI. Tam ten OR też może psuć.
Tak samo to:
status = *AT91C_TWI_SR;
while ( !(status & AT91C_TWI_TXCOMP) )
{
status = *AT91C_TWI_SR;
}
lepiej zapisać tak:
while ( !(*AT91C_TWI_SR & AT91C_TWI_TXCOMP) );
Poza tym jeśli to jest eeprom, to lepiej wysyłać dane sekwencyjnie, a nie po jednym bajcie, za każdym razem wysyłając pełną ramkę (bit startu, adres urządzenia, adres w pamięci, bajt danych i bit stopu). Będzie dużo szybciej. A wysyłanie sekwencyjne realizuje się dosyć łatwo - wystarczy w pętli wpisywać dane do rejestru TWI_THR zaraz po ustawieniu bitu TXRDY w rejestrze TWI_SR. Trzeba tylko wziąc pod uwagę, że zapis sekwencyjny realizowany jest w obrębie jednej strony i po dojściu do jej końca, nie przechodzi na następną, lecz zapisuje tą samą stronę od początku. No i jeszcze nie widzę przy odczycie ustawionego bitu MREAD.
_Matik_, w SAM7S dużo jest uwalone, niestety; ale TWI działa. Najczęstszą przyczyną są albo źle dobrane pullupy, albo źle napisany kod. Datasheet dosyć niejasno opisuje obsługę TWI i niestety brak źródła, które bezsprzecznie potwierdzi, że taki i taki sposób napewno jest dobry i będzie na 100% działać. Np. w kodzie umieszczonym przez
GrzesGrz71 wszystko wygląda w miarę ok, ale w przypadku wysyłania 1 bajtu, nie ustawia w rejestrze TWI_CR bitu MSEN:
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
To może działać, ale nie musi. Jeśli wcześniej ten bit nie został ustawiony, to będą niespodzianki.
kleki, uwagi co do Twojego kodu:
1. To nie jest bascom. Inicjalizację TWI umieść w oddzielnej funkcji. Kod będzie przyjaźniejszy dla oka, a naprawdę niewiele cięższy dla procesora.
2. załączyłeś bibliotekę "AT91SAM7.h", a w niej pewnie znajdują się definicje bitów. Proszę używaj ich. Bo "(7<<16)|(0xFF<<8)|(0xFF);" jest najlepszą drogą do tego żeby popełnić głupi błąd, którego trzeba będzie szukać w ekstremalnych przypadkach nawet przez parę godzin.
Cytat: Nie przekonujecie mnie z tymi pullupami bo jak dobrze rozumiem, wielkosc rezystorow jest uzalezniona tylko i wylacznie od ustawionej predkosci a ja ustawialem juz bardzo male
No niestety, ale nie tylko. Jest uzależniona od pojemności magistrali i układów na niej się znajdujących. Jeżeli pojemność jest większa, to stała czasowa również. Aby zmniejszyć stałą czasową trzeba zmniejszyć rezystancję. Zbocza nie mogą być płaskie nawet przy małych częstotliwościach.
Cytat: Po mojemu bit MRED powinien byc ustawiony na 1, a tam jest jako 0... Wiecie coś bliżej?
Oczywiście, jest źle, ale wystarczy przerzucić parę stron dalej i będzie to jasne.
Dodano po 5 [godziny] 44 [minuty]: A tak BTW, na stronie
http://hubbard.engr.scu.edu/embedded/arm/armlib/ jest do pobrania biblioteka do ARMów, są w niej również biblioteki do SAMów. Jest tam również implementacja TWI. Niezbyt optymalna, ale wygląda na działającą (niestety nie sprawdzałem).
Poza tym właśnie piszę implementację TWI na przerwaniach, żeby nie blokować proca (nie wiem czy ktoś próbował liczyć, ale np. przy częstotliwości proca 48MHz i częstotliwości SCL I2C = 100kHz, wysłanie zwykłej ramki z bitami startu i stopu, adresem urządzenia oraz jednym bajtem danych zajmuje około 10000 cykli procesora). Może zadziała