slideshow 1 slideshow 2 slideshow 3 slideshow 4

Kod na Mikrokontroler

   Kod części odpowiedzialnej za komunikację modułu po stronie mikrokontrolera przedstawiono poniżej:

//Stan poczatowy w modelu. Reset modelu
void CoreResetFpga(void){
   FIOSET1 = uc_rst | uc_wr | uc_rd;
   FIOCLR1 = uc_clk;
   FIOSET1 = uc_clk;
   FIOCLR1 = uc_rst;
   FIOCLR1 = uc_clk;
   FIOSET1 = uc_clk;
}

//Zapis do rejestru modelu
void CoreWriteByteToFpga(unsigned char address, unsigned char value){
   SYS_DATA_DIR = sys_data_out;
   UC_ADR_PIN = address;
   SYS_DATA_PIN = value;
   FIOSET1 = uc_rd;
    FIOCLR1 = uc_rst | uc_wr | uc_clk;
   FIOSET1 = uc_clk;
   FIOSET1 = uc_wr;
   SYS_DATA_DIR = sys_data_in;
}

//Odczyt z rejestru modelu FPGA
void CoreReadByteFromFpga(unsigned char address, unsigned char *value){
   SYS_DATA_DIR = sys_data_in;
   UC_ADR_PIN = address;
   FIOSET1 = uc_wr | uc_rd;
   FIOCLR1 = uc_rst | uc_rd | uc_clk;
   FIOSET1 = uc_clk;
    *value = SYS_DATA_PIN;
   FIOSET1 = uc_rd;
}

W powyzszych przykładach pojawiaja się przypisania zawierające FIOCLR1, UC_ADR_PIN itd. Okreslaja one rejestry mikroprocesora i kryja pod soba definicje:

#define UC_ADR_PIN (*((volatile unsigned char *) 0x3FFFC036))
#define FIOCLR1 (*(volatile unsigned long *) (0x3FFFC03C))

Odpowiednie adresy znajduja się w specyfikacji procesora LPC2148

W przypadku wartości uc_clk, uc_rd itd. ich prawdziwe znaczenie to definicje:

#define uc_clk 0x01000000
#define uc_rd 0x10000000

i oznaczają bit w rejestrze który należy ustawić lub wyzerować

W przypadku wymiany danych pomiedzy mikrokontrolerem a modułem USB przydatne okazują się funkcje:

//Odczytanie pojedynczego bajtu z USB
unsigned char ReadByteFromUsb (void){
   unsigned char tmp;
   SYS_DATA_DIR = sys_data_in;
   while(FIOPIN0 & usb_rxf);
   FIOCLR0 = usb_rd;
   FIOCLR0 = usb_rd;
   FIOCLR0 = usb_rd;
   FIOCLR0 = usb_rd;
   FIOCLR0 = usb_rd;
   tmp = SYS_DATA_PIN;
   FIOSET0 = usb_rd;
   return tmp;
}

//Zapisanie pojedynczego bajtu do USB
void WriteByteToUsb (unsigned char byte){
   SYS_DATA_DIR = sys_data_out;
   while(FIOPIN0 & usb_txe);
   FIOSET0 = usb_wr;
   FIOSET0 = usb_wr;
   SYS_DATA_PIN = byte;
   FIOCLR0 = usb_wr;
   FIOCLR0 = usb_wr;
   SYS_DATA_DIR = sys_data_in;
}

Podsumowanie i literatura

    Nie da się uciec przed magistralami w cyfrowych układach elektronicznych. Stanowią one szkielet prawie każdego zaawansowanego jak i prostego urządzenia. Ich zaprojektowanie wymaga w przypadku dużych projektów wyjątkowej wiedzy, gdyż to właśnie one tworzą szkielet konstrukcji i zapewniają przepływ informacji bez szkodliwych dla systemu wąskich gardeł. Dobrą wiadomością jest to, że bez względu na stopień złożoności projektowanego często to nie one stanowią wyzwanie konstruktora a w przypadku prostych układów są nawet niezauważalne.

Pozycje wykorzystane bezpośrednio do opracowania treści artykułu:

  • [1] Wikipedia. Wydanie angielskie, www. en.wikipedia.org. Pojęcia: Integrated_circuit, Flash_memory, USB, FireWire
  • [2] LVDS Owner’s Manual Including High-Speed CML and Signal Conditioning. Fourth Edition, National Semiconductor 2008
  • [3] FT245BM USB FIFO IC Data Sheet. Revision 1.8, FTDI CHIP, 2008
  • [4] J.Bhasker, Verilog HDL Synthesis, Star Galaxy Publishing, Allentown 1989

Autorem artykułu jest mgr inż. Krzysztof Fijak

Fijak Logic od 2009r