Koleżankom i Kolegom Radioamatorom, Krótkofalowcom,
Konstruktorom i Waszym Rodzinom – w tych trudnych czasach –
Zdrowych, Spokojnych i Pogodnych Świąt Bożego Narodzenia oraz
Szczęśliwego Nowego Roku

Życzy Zespół Home Made


Odpowiedz 
 
Ocena wątku:
  • 0 Głosów - 0 Średnio
  • 1
  • 2
  • 3
  • 4
  • 5
ATxMega128 i TWI - problemy... cd
SP5FCS Offline
Adam
*****

Liczba postów: 1,072
Dołączył: 02-02-2009
Post: #11
RE: ATxMega128 i TWI - problemy... cd
To co zamieściłem wcześniej to są funkcje obsługi warstwy TWI. Na tym trzeba zaimplementować obsługę konkretnych układów. Przykładowy kod zapisu bajtu do wybranego rejestru PCF8563. Do bufora wpisujesz adres rejestru i bajt danych, resztę załatwia funkcja zapisu bufora.

Kod:
#define PCF8563_ADDR            0xA2        //adres zegarka PCF8563

///////////////////////////////////////////////////////////////////////////////////////////////////
// RTC write register
void rtc_write_reg(u8 reg, u8 value)
{
u8 buffer[2];      //buffer

buffer[0]=reg;    //adres rejestru
buffer[1]=value;  //dane
twic_write_buf(PCF8563_ADDR, buffer, 2);                //wysylanie bufora do RTC
}

73 Adam
12-12-2016 21:24
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP2GNB Offline
Staszek sk
****

Liczba postów: 451
Dołączył: 14-02-2015
Post: #12
RE: ATxMega128 i TWI - problemy... cd
Dziękuję.
A jak poradziłeś sobie z zapisem i odczytem c512? Zapis zrobiłem tak:
Kod:
void mem_write_reg(u16 reg, u8 value)
{
u8 buffer[3];      //buffer

buffer[0]=reg/256;    //adres rejestru - starsza część
buffer[1]=reg%256;    //adres rejestru - młodsza część
buffer[2]=value;  //dane
twic_write_buf(mem_ADDR, buffer, 3);                //wysylanie bufora do C512
}
Dobrze?

Z napisaniem procedury odczytu dla adresu 16 bitowego mam problem....

Edit:
Piszę i czytam C512. Praktycznie czytam od adresu '0' co jeden..
Problem podczas zapisu - adres rejestru działa wg wzoru:
adres rejestru=1+4*k gdzie k=0,1,2,3,4.. Taki 'myk' zapewnia zapisywanie do kolejnych komórek pamięci.
Nie wiem czego nie zrozumiałem, ale nie chcę budować żadnych 'protez' w programie. Jak to zrobić dobrze?

73 Staszek SP2GNB
(Ten post był ostatnio modyfikowany: 13-12-2016 15:38 przez SP2GNB.)
13-12-2016 15:25
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #13
RE: ATxMega128 i TWI - problemy... cd
Witaj Staszku,

Nie za bardzo zrozumiałem z Twojego postu z czym masz problem - zapis, odczyt całego bufora ??

Na zapis do pamięci danych z bufora bez magicznych wzorów, które podałeś, można sobie np. tak poradzić:
Kod:
void mem_c512_write( uint16_t reg, uint8_t * bufor, uint8_t len )
{

uint8_t i = len - 1;

do {
  bufor[i + 2] = bufor[ i ];
} while( i--);

bufor[0] = reg >> 8;
bufor[1] = reg & 0xff;


twic_write_buf(mem_ADDR, bufor, len + 2);                //wysylanie bufora do C512
}

W tym przypadku bufor musi mieć co najmniej o 2 bajty większy rozmiar, niż ilość danych do zapisu. Na uwadze też mieć należy to, że zawartość bufora jest modyfikowana.
Nie określiłeś się co dokładnie chcesz zapisywać, odczytywać z/do pamięci. Jeżeli jakieś ustawienia, to może warto rozważyć użycie struktury, a w niej 2 pierwsze bajty zarezerwować dla adresu komórki w pamięci C512 ? Wtedy bez żadnych dodatkowych zabiegów wysyłamy taką strukturę przez i2c ? Rozwiązań jest tyle, ilu programistów...

Przy okazji taka mała sugesia. Staraj się bez potrzeby nie używać operacji dzielenia. Zwiększa to niepotrzebnie rozmiar kodu. Chyba, że ATxmega ma rozkazy sprzętowego dzielenia liczb 16 bitowych.

Przykład pisany "na kolanie".... więc.....

73 Paweł
(Ten post był ostatnio modyfikowany: 13-12-2016 23:19 przez SQ8MVY.)
13-12-2016 23:19
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP2GNB Offline
Staszek sk
****

Liczba postów: 451
Dołączył: 14-02-2015
Post: #14
RE: ATxMega128 i TWI - problemy... cd
Interesująca propozycja - jutro rano wypróbuję.. i wywalę dzielenia...
Podsumowanie:
1. Zegar czytam (ustawiam za pomocą programu Husarka, potem napiszę setup)
2. Pamięć czytam i piszę z jednym problemem:
- czytam podając adres żądanego rejestru np. 0x0024
- do zapisu muszę użyć adresu wg wzoru: adres_rej=4*adres_rej+1 czyli 0x0091
i wtedy zapiszę pod realnym adresem 0x0024. Tego zupełnie nie rozumiem :-(...

Wszystkie procedury Adama i Pawła pracują bardzo dobrze...

BTW:
Ostatnio przeglądnąłem mnóstwo programów (starałem się ze zrozumieniem) i nasunęła mi się myśl. Otóż piszących programy można podzielić na 3 grupy:
1. Wyznawców ortodoksyjnie rozumianego prawa Murphy'ego "Jeśli coś może pójść źle, to na pewno pójdzie źle". W związku z tym mnóstwo komentarzy (bezcenne), pilnowanie rejestrów, zapalanie i gaszenie flag i etc. Takiego podejścia do tematu uczy szkoła asemblerowa...
2. Wyznawców odwróconego prawa Murphy'ego " Jeśli coś może pójść dobrze, to na pewno pójdzie dobrze". Nie ma komentarzy, flagi machają jak chcą ... do czasu ...
3. Całej reszty, która gdzieniegdzie machnie flagą, przynajmniej wiadomo gdzie autor miał kłopoty...

73 Staszek SP2GNB
(Ten post był ostatnio modyfikowany: 14-12-2016 15:44 przez SP2GNB.)
13-12-2016 23:26
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #15
RE: ATxMega128 i TWI - problemy... cd
(13-12-2016 23:26)SP2GNB napisał(a):  - czytam podając adres żądanego rejestru np. 0x0024
- do zapisu muszę użyć adresu wg wzoru: adres_rej=4*adres_rej+1 czyli 0x0091
i wtedy zapiszę pod realnym adresem 0x0024. Tego zupełnie nie rozumiem :-(...

Zaglądnąłem do PDF-a pamięci. Funkcja zapisu z przedstawionych tu przykładów zapisuje pod prawidłowym adresem.
Natomiast funkcję odczytu będzie trzeba zmodyfikować do tej pamięci.....

Strona 11 pdf-a. Mamy pokazany zapis do pamięci pojedynczej danej oraz całego "bufora". Jak widzisz, wysyłamy adres układu, 2 bajty adresu komórki pamięci, oraz dane. Między bajtami jest tylko sygnał ACK i na końcu STOP.

Odczyt już jest z lekka zakręcony.
mamy taką sekwencję::
START -> DEVICE_ADRESS(bit write)->ACK-->MSB_ADRES->ACK->LSB_ADRES->ACK->START->DEVICE_ADRESS(bit read)->ACK->DATA1->NO_ACK->STOP

Zwróć uwagę na wyróżnioną sekwencję START. Występuje bez wcześniejszego STOP !!!

Te funkcje w przykładach chyba nie obsługują takiego odczytu. Nie przeglądałem ich...

Przy okazji, aby się upewnić, czy dane są zapisane pod właściwym adresem, zapisz do niej coś pod znany adres. Następnie w programatorze zewnętrznym odzytaj pamięć. Badzie wszystko wiadomo, gdzie leży błąd. W zapisie pod błędny adres, czy w funkcji odczytu....
PDF pamięci nic nie mówi o takim mechanizmie odczytu/zapisu: adres_rej=4*adres_rej+1.

Nie posiadam aktualnie pamięci c512, oraz Xmegi, więc są to moje rozważania teoretyczne na chwilę obecną.


.pdf  doc1116.pdf (Rozmiar: 503.6 KB / Pobrań: 910)

73 Paweł
(Ten post był ostatnio modyfikowany: 14-12-2016 18:34 przez SQ8MVY.)
14-12-2016 18:26
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP2GNB Offline
Staszek sk
****

Liczba postów: 451
Dołączył: 14-02-2015
Post: #16
RE: ATxMega128 i TWI - problemy... cd
(14-12-2016 18:26)SQ8MVY napisał(a):  Przy okazji, aby się upewnić, czy dane są zapisane pod właściwym adresem, zapisz do niej coś pod znany adres. Następnie w programatorze zewnętrznym odzytaj pamięć. Badzie wszystko wiadomo, gdzie leży błąd. W zapisie pod błędny adres, czy w funkcji odczytu....

Scalak SMD wlutowany na stałe :-( ...
Sprawdzam raz jeszcze...

EDIT:
Wyrzucam wzór z zapisu, traktuję zapis jako OK, grzebię w odczycie...
Rozumiem, że wszystkie sekwencje oprócz read generują automatycznie ACK. Sekwencja read wymaga NOACK ustawianego w CONTROLC..
Taka procedura odczytu dla 8 bitowego adresu rejestru działa bez zarzutu w czytaniu zegara....
Spróbuję zapisać zegar PCF...
Pisze i czytam PCF bez żadnych sztuczek...
Procedura czytania rejestru 16 bitowego wydaje się OK. Kość C512 padła?

73 Staszek SP2GNB
(Ten post był ostatnio modyfikowany: 14-12-2016 19:52 przez SP2GNB.)
14-12-2016 18:49
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #17
RE: ATxMega128 i TWI - problemy... cd
A jakiej funkcji odczytu używasz ?

Tej od Adama:
Kod:
unsigned char twic_read_reg(unsigned char addr, unsigned char reg)
??

Jak tak, to ona musi być zmodyfikowana, bo adres komórki pamięci do odczytu jest wysyłany jako jeden bajt, natomiast dla c512 adres komórki pamięci jest 2-bajtowy.

73 Paweł
14-12-2016 19:01
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP2GNB Offline
Staszek sk
****

Liczba postów: 451
Dołączył: 14-02-2015
Post: #18
RE: ATxMega128 i TWI - problemy... cd
Tak. Po zmodyfikowaniu:
Kod:
unsigned char mem_read_reg(unsigned char addr, uint16_t reg)
{
    uint8_t data;
    //nadaj adres slave + nr rejestru
    TWIC_MASTER_ADDR = addr;                                    //adres ukladu + WR, generuje START
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_WIF_bm));            //wait for WIF
    twic_result = twic_test_result();                            //wez status operacji
    if (twic_result != TWI_ACK) return 0;                        //ACK idz dalej, inny zwracaj kod bledu

    TWIC_MASTER_DATA = (reg & 0xFF00) >> 8;                        // /256 adres rejestru
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_WIF_bm));            //wait for WIF
    twic_result = twic_test_result();                            //wez status operacji
    if (twic_result != TWI_ACK) return 0;                        //ACK idz dalej, inny zwracaj kod bledu

    TWIC_MASTER_DATA = reg & 0x00FF;                            //adres rejestru
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_WIF_bm));            //wait for WIF
    twic_result = twic_test_result();                            //wez status operacji
    if (twic_result != TWI_ACK) return 0;                        //ACK idz dalej, inny zwracaj kod bledu

    TWIC_MASTER_ADDR = addr;                                    //adres ukladu + WR, generuje START
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_WIF_bm));            //wait for WIF
    twic_result = twic_test_result();                            //wez status operacji
    if (twic_result != TWI_ACK) return 0;                        //ACK idz dalej, inny zwracaj kod bledu

    //nadaj adres do odczytu
    TWIC_MASTER_ADDR = addr | 0x01;                                //adres ukladu I2C + RD
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_RIF_bm));            //czekaj na zakonczenie odbioru
    
    data = TWIC_MASTER_DATA;                                    //odczytany bajt

    // send NACK and STOP
    TWIC_MASTER_CTRLC = TWI_MASTER_ACKACT_bm|TWI_MASTER_CMD_STOP_gc;
//    twic_result = TWI_OK;                                        //poprawna operacja
    return data;
}

Coraz bardziej podejrzewam 24C512 - nie mam, muszę zakupić...
Rozebrałem, na pamięci napis ATMLH440. Szukam info...

73 Staszek SP2GNB
(Ten post był ostatnio modyfikowany: 14-12-2016 20:57 przez SP2GNB.)
14-12-2016 20:57
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #19
RE: ATxMega128 i TWI - problemy... cd
Nie podejrzewaj jeszcze pamięci !!!.

W tej Twojej Modyfikacji masz babola.
Wysyłasz 2 bajty adresu komórki pamięci - ok - tak powinno być.

A to co robisz w następnych liniach :
Kod:
TWIC_MASTER_ADDR = addr;                                    //adres ukladu + WR, generuje START
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_WIF_bm));            //wait for WIF
    twic_result = twic_test_result();                            //wez status operacji
    if (twic_result != TWI_ACK) return 0;                        //ACK idz dalej, inny zwracaj kod bledu

    //nadaj adres do odczytu
    TWIC_MASTER_ADDR = addr | 0x01;                                //adres ukladu I2C + RD
    while(!(TWIC_MASTER_STATUS & TWI_MASTER_RIF_bm));            //czekaj na zakonczenie odbioru
    
    data = TWIC_MASTER_DATA;                                    //odczytany bajt
jest prawdopodobnie źle. Zobacz do noty producenta - strona 11

Po wysłaniu adresu komórki pamięci należy wygenerować START podając adres układu slave z ustawionym bitem READ ( addr |0x01 ).

U Ciebie - wysyłasz adres układu z bitem WRITE - generując START i następnie ponownie wysyłasz adres układu ale już z bitem READ - ponownie generując START

I tu się robi (tak mi się wydaje) zamieszanie obecnie...

73 Paweł
(Ten post był ostatnio modyfikowany: 14-12-2016 21:17 przez SQ8MVY.)
14-12-2016 21:16
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP2GNB Offline
Staszek sk
****

Liczba postów: 451
Dołączył: 14-02-2015
Post: #20
RE: ATxMega128 i TWI - problemy... cd
I to było TO!
Święta racja Pawle, ślepnę na starość...
Będziesz w Gdyni to daj znać, przysługuje Ci rybka, frytki i browar...
Dziękuję...

73 Staszek SP2GNB
14-12-2016 21:46
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
Odpowiedz 


Skocz do:


Użytkownicy przeglądający ten wątek: 1 gości