ISIX-RTOS – przykład 3 – obsługa przerwań na przykładzie zegara RTC z magistralą I2C

Kontroler I2C działa na zasadzie zdarzeń, zatem procedura obsługi przerwania sprowadza się do odczytania zdarzenia, a następnie wykonania określonej akcji przypisanej dla tego zdarzenia. W przypadku transmisji danych do układu podłączonego do magistrali I2C, po wysłaniu sekwencji start otrzymujemy zdarzenie informującej o przejęciu arbitrażu nad magistralą I2C przez kontroler. W wyniku wystąpienia zdarzenia I2C_EVENT_MASTER_MODE_SELECTED wywołujemy funkcjesend_7bit_addr(), co powoduje przesłanie adresu sprzętowego dla urządzenia. W wyniku wysłania adresu sprzętowego dostajemy zdarzenie I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED, po którym możemy rozpocząć przesyłać dane. Wraz z każdym przesłanym bajtem otrzymujemy zdarzenie I2C_EVENT_MASTER_BYTE_TRANSMITTED. Oba zdarzenia obsługiwane są przez ten sam fragment programu, którego zadaniem jest wysłanie danych z bufora. W przypadku, przesłania ostatniego bajtu, jeżeli nie ma konieczności odbierania danych, jest wywoływana metoda powodująca wygenerowanie sekwencji stop, następnie jest podnoszony semafor sem_irq informujący wątek o zakończeniu obsługi przerwania. Realizacja podnoszenia semafora odbywa się za pomocą metody sem_signal_isr(), która jest przeznaczona do wywołania z procedur obsługi przerwań. Jeżeli po zakończeniu nadawania konieczne jest odbieranie danych z urządzenia, generowany jest ponownie bit startu oraz przesyłany jest adres sprzętowy, z najmłodszym bitem ustawionym do odczytu. W wyniku przesłania adresu sprzętowego otrzymujemy zdarzenie I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED, w którym sprawdzamy, czy mamy do odebrania jeden bajt. Jeżeli tak jest, to wyłączamy generowanie bitu ACK, a następnie przechodzimy do odbioru kolejnych danych. W przypadku odebrania bajtu otrzymujemy zdarzenie I2C_EVENT_MASTER_BYTE_RECEIVED, gdzie realizujemy przepisywanie bajtów do bufora odbiorczego. Gdy skończymy odbieranie przedostatniego bajtu zgodnie ze specyfikacją I2C wyłączamy generowanie bitu potwierdzenia ACK, a po odebraniu ostatniego bajtu wysyłamy polecenie wygenerowania sekwencji stop oraz podnosimy semafor sem_isr informujący o zakończeniu procedury odbioru. Po wygenerowaniu sekwencji stop magistrala I2C zostaje zwolniona.
Klasa sterownika i2c wykorzystywana jest przez klasęrtc_reader, której zadaniem jest odczytanie bieżącej godziny z zegara RTC oraz przygotowanie i przesłanie komunikatów do obiektu serwera wyświetlacza. Działanie wątku odpowiedzialnego za to zadanie realizowane jest przez metodę wirtualną pokazaną na list. 7.

List. 7. Metoda wirtualna przygotowująca i przesyłająca komunikaty do obiektu serwera wyświetlacza

Pierwszą czynnością jest ustawienie wartości początkowej daty i czasu. Wartości początkowe zdefiniowane są w tablicy pgm_regs. W rzeczywistej aplikacji należało by zadbać o możliwość odczytania danych z interfejsu użytkownika. Przesłanie wartości początkowych realizowane jest za pomocą funkcji i2c_transfer_7bit. Następnie wchodzimy do pętli głównej programu, gdzie realizowany jest odczyt bieżącej godziny z zegara RTC. Zgodnie z dokumentacją układu najpierw należy zapisać adres pierwszego rejestru do odczytu, następnie należy przesłać ponownie adres sprzętowy z ustawionym bitem read, a następnie odczytać rejestry zegara. Cała procedura odbywa się poprzez wywołanie pojedynczej metody i2c_transfer7bit(). Po odczytaniu danych z magistrali I2C sprawdzany jest status błędu. W przypadku wystąpienia błędu wysyłany jest komunikat tekstowy. Jeżeli odczyt danych z magistrali I2C wykonano pomyślnie, jest tworzony komunikat klasy time_msg, zawierający informację o czasie w formie tekstowej, który następnie przesyłany jest do serwera wyświetlania. Klasa time_msg dziedziczy z klasy text_msg, zatem może być wysłana bezpośrednio do serwera wyświetlania:

List. 8.

Utworzenie komunikatu tekstowego zawierającego aktualny czas odbywa się przez wywołanie metody set_time(), która jako argumenty przyjmuje aktualną godzinę minutę i sekundę w formacie BCD. W wyniku wykonania tej metody powstaje komunikat tekstowy, który jest wykorzystywany przez serwer wyświetlania.

Do pobrania

O autorze