Forum: Ders Arası RSS
Paralel port için D ilintileri
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Paralel port için D ilintileri
Merhaba. Şimdi <sys/io.h> dosyasındaki kodun D için ilintisini yazmaya çalışıyorum. Ama içteki assembly kodunun çevrilmesinde takıldım.

sys/io.h başlık dosyası

static __inline void outb (unsigned char value, unsigned short int port)
{
    __asm__ __volatile__ ("outb %b0,%w1"
                          :
                          :
                          "a" (value),
                          "Nd" (port));
}

io.d
 
extern(C) 
{
    void outb (ubyte value, ushort port)
    {
        // bu kısımda takıldım
    }
    
}
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Oy! Bir bilene sormak gerek. :)

Tamamen uydurarak bir deneme yanılma fikri: gcc'nin oluşturduğu assembly çıktısına bakılır, dmd'nin out, outsb, vs. asm komutları denenerek aynısı tutturulmaya çalışılır:

  http://dlang.org/iasm.html

Ali
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet ben de verdiğiniz sayfaya baktım ve bu sayfaya da bakmıştım.

http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

Aslında eskiden biliyordum biraz assembly  :-p

Burada bir şey buldum ama umarım çalışır :)

http://stackoverflow.com/questions/1385487/converting-prob…
erdem (Moderatör) #4
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
extern(C) 
{
    void outb (ubyte value, ushort port)
    {
        asm
        {
            mov AL, value;
            mov DX, port;
            out DX, AL;
        }
    }
}

Şu kod teorik olarak derleniyor. Ama pratikte çalışır mı ya da yapılmak istenen işi yapar mı  :-D  

Evde test etmem lazım :)
erdem (Moderatör) #5
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu soruyu stackoverflow.com'da da sordum. Yanıt da gelmiş. Sanırım aynen benim yazdığım gibi oluyormuş.

http://stackoverflow.com/questions/8614721/converting-help…

Anladığım kadarıyla aslında D'nin sunduğu core.bitop.outp olanağı sayesinde assembly bile kullanmaya bile gerek yokmuş.

void portayaz (ubyte değer, ushort port)
{
    import core.bitop;
    portayaz(port, değer);
}

Heyo! :) Şimdi akşam denemem lazım.
Bu mesaj erdem tarafından değiştirildi; zaman: 2011-12-23, 03:03.
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Güzel! Ama kendini çağırmayacaksın tabii: :D

void portayaz (ubyte değer, ushort port)
{
    import core.bitop;
    outp(port, değer);
}

Ali
erdem (Moderatör) #7
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet süper çalıştı! :)


/* io.d */
 
import std.stdio;
import core.bitop;
 
alias outp yaz;
alias ioperm erişimhakları;
 
extern(C)
{
/*
   void outb (ubyte value, ushort port)
    {
        asm 
        {
            mov AL, value;
            mov DX, port;
            out DX, AL;
        }
    }
*/
 
    int ioperm (int __from, int __num, int __turn_on) ;
}

/* lcdpanel.d */
 
import std.stdio;
import io;
import core.thread;
import std.string;
 
const uint adres = 0x0c000;
const uint kontrol = 0x0c002;
 
void main()
{      
    erişimhakları(adres,1,1);  
    erişimhakları(kontrol,1,1);    
 
    /* veri uçlarını 0 kontrol uçlarını 1 yap */    
    yaz(adres,0);
    yaz(kontrol,0);
 
    /*
      paneli aç imleci kapat yanıp sönmeyi kapat
      1 P İ Y
      1 1 0 0
    */
    komutGonder(0b_1111);  
    
    /*
      ekranı temizle
      0 0 0 1
    */        
    komutGonder(0b_0001);
    
    komutGonder(56);
    komutGonder(128);
 
    string mesaj = "Dunyada her aklibasinda ulkenin arastirmada da, bilim teknikte" "  de, sanayide de,"
                   "dis siyasette,  hepsinin uzun   vadeli hedeflerivardir kesinkes ve uzun sure" "    bunlar "
                   "gider.";
    yazıGönder(mesaj);    
}
 
void yazıGönder(string mesaj)
{
    for(int i = 0; i != mesaj.length; ++i) {    
    if ((i % 16) == 0) {
        if((i % 32) == 0) {
                komutGonder(1);
            } else {
                komutGonder(128+64);
             }        
        }
        veriGonder(mesaj[i]);
    }
}
 
 
void komutGonder(ubyte veri)
{
    /* veri gönderiyoruz */
    yaz(adres,veri);
    
    /*
      RS girişi C3 düşük yaparak
      lcd panelin komut saklayıcısını seçiyoruz
      1000
    */
    yaz(kontrol,8);
 
    /* Yarım saniye bekliyoruz */
    Thread.sleep(dur!"msecs"(80));
 
    /*
      E ucu C0 da düşük yapılarak komut gönderiliyor 
      1001
    */    
    yaz(kontrol,9);    
    Thread.sleep(dur!"msecs"(80))}
 
void veriGonder(ubyte veri)
{
    yaz(adres, veri);
 
    /* 
      C0 yüksek yapılıyor
      0 0 0 0
    */
    yaz(kontrol,0);
    Thread.sleep(dur!"msecs"(80));  
 
    /*    
      biraz bekledikten sonra tekrar düşük
      yapılarak veri gönderiliyor
      0 0 0 1
    */
    yaz(kontrol,1);    
    Thread.sleep(dur!"msecs"(80));    
}

Bir lcd paneli D ile programlamak güzel :) Programı derlemek için dmd lcdpanel.d io.d ile derlemek ve sonra sudo ./lcdpanel ile çalıştırmak yeterli.

Yalnız gene de Ali beye bir sorum olacak. Örneğin ioperm işlevinin orjinal başlık dosyasındaki işlev bildirim şu şekilde:

extern int ioperm (unsigned long int __from, unsigned long int __num,
           int __turn_on) __THROW;

Bu nasıl bir şeydir :)

Ayrıca LCD panel 2 x 16 olduğu için her 16 karakterde bir alt satıra geçmek. 32 karakterden sonra da ekranı temizleyip tekrar ilk satırdan devam etmek gerekiyor. Benim yaptığım çözüm biraz kaba oldu  :-D

Bir de uzun bir cümle girildiğinde bir sonraki kelime ilk satıra sığmıyorsa ikinci satıra yazsın. Gene ikinci satırdayken de kelimeyi yazacak yer kalmadıysa (yarım yazmak yerine) ekranı temizleyip ilk satırdan yazsın. Buna yazılımsal olarak nasıl bir çözüm bulabiliriz acaba.

Hatta biraz daha ilerisi. Bir metin dosyasındaki metinleri rastgele seçip biraz bekledikten sonra ekrana yazsın. Türkçe karakter destekleyen LCD panel var mı acaba :o)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
erdem:
Evet süper çalıştı! :)

Müthişsin! :)

Bir lcd paneli

Güzel bir oyuncak.

ioperm işlevinin orjinal başlık dosyasındaki işlev bildirim şu şekilde:

extern int ioperm (unsigned long int __from, unsigned long int __num,
           int __turn_on) __THROW;

Bu nasıl bir şeydir :)

Benim /usr/include/sys/cdefs.h dosyamda şöyle diyor (önemsiz yerlerini çıkartıyorum):

/* GCC can always grok prototypes.  For C++ programs we add throw()
   to help it optimize the function calls.  But this works only with
   gcc 2.8.x and egcs.  For gcc 3.2 and up we even mark C functions
   as non-throwing using a function attribute since programs can use
   the -fexceptions options for C code as well.  */
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
#  define __THROW    __attribute__ ((__nothrow__))
// ...
# elseif defined __cplusplus && __GNUC_PREREQ (2,8)
#   define __THROW    throw ()
// ...else
#   define __THROW
// ...
#  endif
# endif

Yani oradaki __THROW, kullanılan derleyiciye ve dile (C veya C++) göre farklı oluyor. throw(), C++ standardında "bu işlev hata atmaz" anlamına gelir. __attribute__ ise gcc'nin kendisiyle ilgili ek olanaklardır ve anlaşılan __attribute__ ((__nothrow__)) da aynı anlama geliyor.

Bir işlevin hata atmıyor olduğunun denetlenebileceği umulmuştu ama bu C++ olanağı fos çıktı. Programların farklı kaynak dosyalar olarak derlenebiliyor olmaları nedeniyle derleyiciler bu konuda umulan denetimi getiremediler. Onun için yukarıdaki açıklamada da bunun eniyileştirme amacıyla kullanılabileceği söyleniyor.

D ilintisindeki karşılığı nothrow olabilir:

  http://ddili.org/ders/d/islevler_diger.html

Dener misin...

Ayrıca LCD panel 2 x 16 olduğu için her 16 karakterde bir alt satıra geçmek. ... Bir de uzun bir cümle girildiğinde bir sonraki kelime ilk satıra sığmıyorsa ikinci satıra yazsın.

Bence bir standart kütüphanede bulunmayacak kadar özel bir ihtiyaç ama std.string.wrap diye bir işlev var: :)

  http://dlang.org/phobos/std_string.html#wrap

Bu gibi konularda yararlı olabilecek başka std.string işlevleri de var: center, rightJustify.

32 karakterden sonra da ekranı temizleyip tekrar ilk satırdan devam etmek gerekiyor.

wrap'in döndürdüğü dizgiyi kullanarak onu yine de senin yapman gerekiyor galiba.

Hatta biraz daha ilerisi. Bir metin dosyasındaki metinleri rastgele seçip biraz bekledikten sonra ekrana yazsın.

O kolay. :)

Türkçe karakter destekleyen LCD panel var mı acaba :o)

Levent Saltuklaroğlu hocanın şöyle bir yazısını buldum (kendisine sorulabilir):

  http://www.codeproject.com/KB/cs/cspplcds.aspx

Yazıda "font" sözcüğünün geçtiği ikinci yerde bir tablo var. O tablonun üzerine yazılabiliyor galiba çünkü yorumlar arasında Unicode'un geçtiği yerde "RAM" deniyor.

İyi eğlenceler! :)

Ali
erdem (Moderatör) #9
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
ioperm işlevinin orjinal başlık dosyasındaki işlev bildirim şu şekilde:

extern int ioperm (unsigned long int __from, unsigned long int __num,
           int __turn_on) __THROW;


Benim /usr/include/sys/cdefs.h dosyamda şöyle diyor (önemsiz yerlerini çıkartıyorum):

/* GCC can always grok prototypes.  For C++ programs we add throw()
   to help it optimize the function calls.  But this works only with
   gcc 2.8.x and egcs.  For gcc 3.2 and up we even mark C functions
   as non-throwing using a function attribute since programs can use
   the -fexceptions options for C code as well.  */
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
#  define __THROW    __attribute__ ((__nothrow__))
// ...
# elseif defined __cplusplus && __GNUC_PREREQ (2,8)
#   define __THROW    throw ()
// ...else
#   define __THROW
// ...
#  endif
# endif

D ilintisindeki karşılığı nothrow olabilir:

Evet bu nothrow'u deneyeceğim. Ama Ali bey benim burada kafamı en çok karıştıran aldığı parametrelerin iki tane olmasıydı. 

int ioperm (ulong int __from ..) ..

Burada hem ulong hem int var nasıl bir işlevdir diye düşündüm :) Ama anladığım kadarıyla D'ye çevirirken bahsettiğiniz nothrow özelliğini kullanmak yeterli.

acehreli:
Türkçe karakter destekleyen LCD panel var mı acaba :o)

Levent Saltuklaroğlu hocanın şöyle bir yazısını buldum (kendisine sorulabilir):

  http://www.codeproject.com/KB/cs/cspplcds.aspx

Yazıda "font" sözcüğünün geçtiği ikinci yerde bir tablo var. O tablonun üzerine yazılabiliyor galiba çünkü yorumlar arasında Unicode'un geçtiği yerde "RAM" deniyor.

Aslında bu kısmı yaptım.

http://www.geocities.com/dinceraydin/lcd/custom.htm

Ama Türkçe'deki özel karakter sayısı 12. 2 tanesi zaten var. Geriye 10 tane kalıyor. CGRAM'e 8 karakter yazabiliyormuşuz sanırım. O yüzden 2 karakter eksik kalıyor.

Eğer DDRAM'e yazmanın bir yolu yoksa donanım kısıtlaması yaşıyoruz sanırım.  Bu yüzden ben de programın diğer bölümlerini geliştirmekten vazgeçtim.

Ya da kırmanın bir yolu yokmudur acaba :)

import std.stdio;
import io;
import core.thread;
import std.string;
 
const uint adres = 0x0c000;
const uint kontrol = 0x0c002;
 
void main()
{      
    erişimhakları(adres,1,1);  
    erişimhakları(kontrol,1,1);    
 
    türkçeKarakterleriGir();
    
    komutGönder(1);
    komutGönder(15);
   
    /* ilk satırın ilk karakterine git */    
    komutGönder(128);
 
    /* türkçe karakterleri yaz */
    for(ubyte i = 0; i < 8; ++i)  
         veriGönder(i);
 
    /* ikinci satırın ilk karakterine git */  
    komutGönder(192);
 
    string mesaj = "Türkçe yazıyorum";    
 
    foreach (wchar harf; mesaj) {
        switch(harf) {
            case('ç'):
                veriGönder(0);
                break;
            case('ı'):
                veriGönder(3);
                break;
            case('ü'):
                veriGönder(245);
                break;
            default:  
                veriGönder(cast(ubyte)(harf));
                break;
        }              
    }
}
 
void türkçeKarakterleriGir()
{
    komutGönder(12);
    komutGönder(1);
    komutGönder(56);
 
    komutGönder(64);   
    
    const ubyte[8] çharfi = [0x00, 0x00, 0x0e, 0x10, 0x10, 0x11, 0x0e, 0x04]; // ç harfi = 0
    const ubyte[8] ğharfi = [0x0e, 0x00, 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x0e]; // ğ harfi = 1
    const ubyte[8] şharfi = [0x00, 0x00, 0x0e, 0x10, 0x0e, 0x01, 0x1e, 0x04]; // ş harfi = 2
    const ubyte[8] ıharfi = [0x00, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x0e, 0x00]; // ı harfi = 3
    /*
      ö harfi = 239
      ü harfi = 245
    */
 
    ubyte[8] Çharfi = [14, 17, 16, 16, 16, 17, 14, 4];
    ubyte[8] Ğharfi = [0x0e, 0x00, 0x1f, 0x10, 0x13, 0x11, 0x1f, 0x00];
    ubyte[8] Şharfi = [0x0e, 0x11, 0x10, 0x0e, 0x01, 0x15, 0x0e, 0x04];
    ubyte[8] Öharfi = [100, 14, 17, 17, 17, 14, 0];
 
    karakterGönder(çharfi);
    karakterGönder(ğharfi);
    karakterGönder(şharfi);
    karakterGönder(ıharfi);
 
    karakterGönder(Çharfi); 
    karakterGönder(Ğharfi);     
    karakterGönder(Şharfi);  
    karakterGönder(Öharfi);   
}
 
void karakterGönder(ubyte[8] karakter)
{
   foreach (satır;karakter) {
    yaz(kontrol,0);
    Thread.sleep(dur!"msecs"(20)); 
    yaz(adres,satır);
    yaz(kontrol,1);
    Thread.sleep(dur!"msecs"(20)); 
   }
}
 
void veriGönder(ubyte veri)
{
    yaz(kontrol,0);
    Thread.sleep(dur!"msecs"(80)); 
    yaz(adres,veri);
    yaz(kontrol,1);
    Thread.sleep(dur!"msecs"(80)); 
}
 
void komutGönder(ubyte veri) 
{
    yaz(kontrol,8);
    Thread.sleep(dur!"msecs"(80));
    yaz(adres,veri);
    yaz(kontrol,9);
    Thread.sleep(dur!"msecs"(80));
}
acehreli (Moderatör) #10
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
aldığı parametrelerin iki tane olmasıydı. 

int ioperm (ulong int __from ..) ..

Burada hem ulong hem int var

C ve C++'ta long int ile long aynı anlama gelir. O yüzden unsigned long int yerine D'de ulong gelmeli.

CGRAM'e 8 karakter yazabiliyormuşuz sanırım

O zaman bazı karakterler aynı yeri paylaşabilirler mi? En sondaki yazdırma işlevin 8 konumda hangi karakterlerin bulunduğunu bilir ve o zamandaki kullanımlarına bakarak en az kullanılmış olanın üzerine eksik karakteri yazar.

Ali
erdem (Moderatör) #11
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
O yüzden unsigned long int yerine D'de ulong gelmeli.

Hımm. Çok teşekkürler.

O zaman aslında unsigned long int tek bir değişken türünü gösteriyor anladığım kadarıyla. Yani int gibi. Ben ilk planda değişken türlerine bakarak sanki iki parametre alıyormuş gibi düşünmüştüm.

acehreli:
CGRAM'e 8 karakter yazabiliyormuşuz sanırım

O zaman bazı karakterler aynı yeri paylaşabilirler mi? En sondaki yazdırma işlevin 8 konumda hangi karakterlerin bulunduğunu bilir ve o zamandaki kullanımlarına bakarak en az kullanılmış olanın üzerine eksik karakteri yazar.

Demek istediğinizi anladım sanırım. O zaman 8 karakter belirli yerlerde bulunacak. Son 2 karakteri de ilkönce karakter olarak CGRAM'e yazacağız. Sonra ekrana yazacağız. Tabi bu arada bir gecikme olur mu emin değilim.

Bunu da bir deneyeyim bakalım :)
erdem (Moderatör) #12
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #10
acehreli on 2011-12-28, 07:32:
C ve C++'ta long int ile long aynı anlama gelir.

O zaman aslında unsigned long int tek bir değişken türünü gösteriyor anladığım kadarıyla.

Bazen jeton köşeli olduğu için düşmesi uzun sürebiliyor :) Burada aslında sorunun cevabını vermişsiniz. Ben kaçırmışım.

Bu arada elektronik gerçekten çok zevkli  ;-)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 22:46:35 (UTC -08:00)