Selamlar
PSoC'da C ile çalışırken uygulamış olduğum bir kod parçası var.
for(clm=0;clm<32;clm++)
{
read_color(clm,row, &red_bits[0], &green_bits[0], &blue_bits[0]);
disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);
disp_data[clm]|=(((blue_bits[0]>>bitmask)*4)& 0x04)|(((green_bits[0]>>bitmask)*2)&0x02)|((red_bits[0]>>bitmask)& 0x01);
HUB_Write(disp_data[clm]);
CLK_Write(1);CLK_Write(0);
}
Bu kodum 64Mhz de çalışan Psoc için yaklaşık olarak 80uS sürüyor. Yaptığım işlem şudur.
16x32 boyutlarında bir Ram alanım var. Satır ve sütün indexlerine göre read_color fonksiyonu içerisinde ilgili bölümleri red_bits, green_bits ve blue_bits değişkenlerine alıyorum
Fonksiyonun içeriği aşağıdaki gibi.
void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
rbits[0]=(display_ram[clm][row]>>8)&0x000F;
gbits[0]=(display_ram[clm][row]>>4)&0x000F;
bbits[0]=display_ram[clm][row]&0x000F;
rbits[1]=(display_ram[clm][row+8]>>8)&0x000F;
gbits[1]=(display_ram[clm][row+8]>>4)&0x000F;
bbits[1]=display_ram[clm][row+8]&0x000F;
}
Daha sonra 4 bitten oluşan bu renk datalarının bitmask değişkeni ile belirlediğim bitlerini disp_data değişkenine alt alta dizip Dışarıya vermem gerekiyor.
Tabi C'de yapılabilecekler biraz sınırlı. Optimizasyon konusunda biraz tavsiye almak istiyorum. Bunun dışında PSoC'ların içerisinde FPGA benzeri yapılar var. Orada verilog ile paralel işlem yapmam mümkün.
Yarın aşağıdaki kod parçasını PGA ile yapmaya çalışacağım
disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);
disp_data[clm]|=(((blue_bits[0]>>bitmask)*4)& 0x04)|(((green_bits[0]>>bitmask)*2)&0x02)|((red_bits[0]>>bitmask)& 0x01);
HUB_Write(disp_data[clm]);
CLK_Write(1);CLK_Write(0);
Bunun dışında başka nasıl optimizasyonlar uygulanabilir?
DMA diyecem ama maskelemeler var. Taşımaları DMA üzerinden maskelemeleri kodla devam et mesela :)
Hocam bu satırı komple Verilog'da FPGA ile yapabilirim diye düşünüyorum.
disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);
disp_data[clm]|=(((blue_bits[0]>>bitmask)*4)& 0x04)|(((green_bits[0]>>bitmask)*2)&0x02)|((red_bits[0]>>bitmask)& 0x01);
HUB_Write(disp_data[clm]);
CLK_Write(1);CLK_Write(0);
Öyle olsa tek clock'da çözülür. Ama asıl elimi ayağımı bağlıyan read_color fonksiyonu. Bu fonksiyon üzerinde neler yapılabilir onu düşünüyorum.
disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);
Eğer optimizasyon yukarıdaki satırı aşağıdakine çevirmeyip and işlemi yapıyorsa aşağıdaki kod biraz olsun işi hızlandırır.
disp_data[clm]=(((blue_bits[1]>>bitmask)*32))|(((green_bits[1]>>bitmask)*16))|(((red_bits[1]>>bitmask)*8));
Eğer bitmask değerin sabit ise ve değerini bilirsek belki daha başka sadeleşme de yapılabilir.
Abi yok o maskelemeyi yapmak zorundayım. Çünkü maskelemeyi 0. bitten itibaren yapıyorum. Bu işlemlerin hepsini verilog da yapabilirim diye düşünüyorum. Bu işlemleri FPGA ile yapabilirsem belkide 1-2 clock'da işlemler yapılır hepsi.
Cevabın bana ise verdiğim kod ile senin kod birbirine eşdeğer.
Yanlış çalışıyor ama abi ??? Gerçekte denedim.
blue_bits, green_bits ve red_bits değerleri 4 bitlik değerler. bitmask değeri 0-3 arası değişiyor.
Bu 4 bitlik değerleri sıra ile 0. 1. 2. ve 3. bitlerini alıp disp_data'nın ilk 6 bitine yerleştiriyorum.
Hocam C'de Shift işlemi kaç clockda yapılır?
void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
rbits[0]=(display_ram[clm][row]>>8)&0x000F;
gbits[0]=(display_ram[clm][row]>>4)&0x000F;
bbits[0]=display_ram[clm][row]&0x000F;
rbits[1]=(display_ram[clm][row+8]>>8)&0x000F;
gbits[1]=(display_ram[clm][row+8]>>4)&0x000F;
bbits[1]=display_ram[clm][row+8]&0x000F;
}
void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
temp = display_ram[clm][row] ;
rbits[0]=(temp >> 8) & 0x000F;
gbits[0]=(temp >> 4) & 0x000F;
bbits[0]=temp & 0x000F;
temp = display_ram[clm][row+8] ;
rbits[1]=(temp >>8) & 0x000F;
gbits[1]=(temp >>4) & 0x000F;
bbits[1]=temp & 0x000F;
}
belki şöyle dahada hızlı çalışır:
void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
temp = display_ram[clm][row] ;
bbits[0]=temp & 0x000F;
temp = (temp >> 4)
gbits[0]= temp & 0x000F;
rbits[0]=(temp >> 4) & 0x000F;
temp = display_ram[clm][row+8] ;
bbits[1]=temp & 0x000F;
temp = (temp >> 4)
gbits[1]=temp & 0x000F;
rbits[1]=(temp >>4) & 0x000F;
}
İşlemci 16 bit ise ve SWAP vede SWAP.B komutları varsa dahada optimize edilir.