Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

Sequencial protocol comunication

Hi dears, im new in this forum, and no so far with fpga knowledge.

But ok im trying to learn, i post an experiment i want to comunicate with external component that have:

16 bit address/command

reset signal

chip select signal

and ahother 2 bits this doesnt matter. That i do work and work well... but i think that i dont are in the correct way... i have the feeling that could be more easy or "efficient"

this is my principal verilog:


module video_controller (input clock ,input start  ,input  color_in, input  x, input  y, input  h, input  w,output reg  data,output reg  latches,output  finish,output  color_in_next, output reg rst); 
reg  i_counter=0;
//                          cs_rd_wr_rs
localparam  StartCmd=4'b0101; 
localparam  EndCmd=4'b1111; 
localparam  StartIdx=4'b0100; 
localparam  EndIdx=4'b1110; 
reg  init = 1'b1;
always@(posedge clock && init)
begin
i_counter<=i_counter+1;
//if(i_counter>7000)i_counter<=0;
case (i_counter)
10 :rst=1'b0;
1000 :rst=1'b1;
1010 :latches=StartIdx;
1020 :data=8'h01;
1030 :latches=EndIdx;
2000 :latches=StartIdx;
2010 :data=8'h01;
2020 :latches=EndIdx;
3000 :latches=StartIdx;
3010 :data=8'h01;
3020 :latches=EndIdx;
4000 :latches=StartIdx;
4010 :data=8'he0;
4020 :latches=EndIdx;
5000 :latches=StartCmd;
5010 :data=8'h01;
5020 :latches=EndCmd;
6000 :latches=StartIdx;
6010 :data=8'he0;
6020 :latches=EndIdx;
6030 :latches=StartCmd;
6040 :data=8'h03;
6050 :latches=EndCmd;
6050 :latches=StartIdx;
6060 :data=8'hb0;
6070 :latches=EndIdx;
6080 :latches=StartCmd;
6090 :data=8'h08;
6100 :latches=EndCmd;
6110 :latches=StartCmd;
6120 :data=8'h80;
6130 :latches=EndCmd;
6140 :latches=StartCmd;
6150 :data=8'h03;
6160 :latches=EndCmd;
6170 :latches=StartCmd;
6180 :data=8'h1f;
6190 :latches=EndCmd;
6200 :latches=StartCmd;
6210 :data=8'h01;
6220 :latches=EndCmd;
6230 :latches=StartCmd;
6240 :data=8'hdf;
6250 :latches=EndCmd;
6260 :latches=StartCmd;
6270 :data=8'h00;
6280 :latches=EndCmd;
6290 :latches=StartIdx;// PIXEL DATA INTERFACE
6300 :data=8'hF0;
6310 :latches=EndIdx;
6320 :latches=StartCmd;
6330 :data=8'h3;
6340 :latches=EndCmd;
6350 :latches=StartIdx;// PIXEL FORMAT
6360 :data=8'h3a;
6370 :latches=EndIdx;
6380 :latches=StartCmd;
6390 :data=8'h50;
6400 :latches=EndCmd;
6410 :latches=StartIdx;//SET PCLK freq=33.26MHz
6420 :data=8'he6;
6430 :latches=EndIdx;
6440 :latches=StartCmd;
6450 :data=8'hff;
6460 :latches=EndCmd;
6470 :latches=StartCmd;
6480 :data=8'hff;
6490 :latches=EndCmd;
6500 :latches=StartCmd;
6510 :data=8'hff;
6520 :latches=EndCmd;
6530 :latches=StartIdx;//SET HBP, HFP
6540 :data=8'hb4;
6550 :latches=EndIdx;
6560 :latches=StartCmd;
6570 :data=8'h20;
6580 :latches=EndCmd;
6590 :latches=StartCmd;
6600 :data=8'haf;
6610 :latches=EndCmd;
6620 :latches=StartCmd;
6630 :data=8'h00;
6640 :latches=EndCmd;
6650 :latches=StartCmd;
6660 :data=8'ha3;
6670 :latches=EndCmd;
6680 :latches=StartCmd;
6690 :data=8'h07;
6700 :latches=EndCmd;
6710 :latches=StartCmd;
6720 :data=8'h00;
6730 :latches=EndCmd;
6740 :latches=StartCmd;
6750 :data=8'h00;
6760 :latches=EndCmd;
6770 :latches=StartCmd;
6780 :data=8'h00;
6790 :latches=EndCmd;
endcase 
end
endmodule

And the same code in C is


void TFT_SSD1963_8bit_Set_Index(uint8_t index) 
{
        CS_RESET();
        RD_SET();
        RS_RESET();
    
        DATA_PORT(index);
        WR_RESET();
        WR_SET();
        CS_SET();
    
}
void TFT_SSD1963YT_8bit_Write_Command(uint8_t command)
 {
   CS_RESET();
   RD_SET();
   RS_SET(); 
   DATA_PORT(command);
   WR_RESET();
   WR_SET();
   CS_SET();
}
   RST_SET();        
   TFT_SSD1963_8bit_Set_Index(0x01);     //Software Reset
     for(i=0;i<0x80000;i++){}
   TFT_SSD1963_8bit_Set_Index(0x01);
     for(i=0;i<0x80000;i++){}
   TFT_SSD1963_8bit_Set_Index(0x01);
     for(i=0;i<0x80000;i++){}
   TFT_SSD1963_8bit_Set_Index(0xe0); //START PLL
     for(i=0;i<0x80000;i++){}
   TFT_SSD1963YT_8bit_Write_Command(0x01);
     for(i=0;i<35000;i++){}
   // Wait 100us to let the PLL stable
   TFT_SSD1963_8bit_Set_Index(0xe0);//LOCK PLL
   TFT_SSD1963YT_8bit_Write_Command(0x03);
   TFT_SSD1963_8bit_Set_Index(0xb0); //SET LCD MODE  SET TFT 18Bits MODE
   TFT_SSD1963YT_8bit_Write_Command(0x08); //SET TFT MODE & hsync+Vsync+DEN
   //MODE
   TFT_SSD1963YT_8bit_Write_Command(0x80); //SET TFT MODE & hsync+Vsync+DEN
   //MODE
   TFT_SSD1963YT_8bit_Write_Command(0x03); //SET horizontal size
   //HightByte
   TFT_SSD1963YT_8bit_Write_Command(0x1f);        //SET horizontal size
   //LowByte
   TFT_SSD1963YT_8bit_Write_Command(0x01); //SET vertical size
   //HightByte
   TFT_SSD1963YT_8bit_Write_Command(0xdf); //SET vertical size LowByte
   TFT_SSD1963YT_8bit_Write_Command(0x00); //SET even/odd line RGB seq.=RGB
   TFT_SSD1963_8bit_Set_Index(0xF0);// PIXEL DATA INTERFACE
   TFT_SSD1963YT_8bit_Write_Command(0x3); 
   TFT_SSD1963_8bit_Set_Index(0x3A);// PIXEL FORMAT
     TFT_SSD1963YT_8bit_Write_Command(0x50);
   TFT_SSD1963_8bit_Set_Index(0xe6);    //SET PCLK freq=33.26MHz
     TFT_SSD1963YT_8bit_Write_Command(0xFF);//REFRESCO AL MAXIMO
   TFT_SSD1963YT_8bit_Write_Command(0xFF);//REFRESCO AL MAXIMO
   TFT_SSD1963YT_8bit_Write_Command(0xFF);//REFRESCO AL MAXIMO
   TFT_SSD1963_8bit_Set_Index(0xb4); //SET HBP, HFP
   TFT_SSD1963YT_8bit_Write_Command(0x20); //SET HSYNC
   TFT_SSD1963YT_8bit_Write_Command(0xaf);
   TFT_SSD1963YT_8bit_Write_Command(0x00); //SET HBP
   TFT_SSD1963YT_8bit_Write_Command(0xa3);
   TFT_SSD1963YT_8bit_Write_Command(0x07);//SET VBP
   TFT_SSD1963YT_8bit_Write_Command(0x00);//SET Hsync pulse start position
   TFT_SSD1963YT_8bit_Write_Command(0x00);
   TFT_SSD1963YT_8bit_Write_Command(0x00);//SET Hsync pulse subpixel start
   //position
   TFT_SSD1963_8bit_Set_Index(0xb6);//SET VBP, VFP
   TFT_SSD1963YT_8bit_Write_Command(0x01);//SET Vsync
   TFT_SSD1963YT_8bit_Write_Command(0xef);
   TFT_SSD1963YT_8bit_Write_Command(0x00);//SET VBP
   TFT_SSD1963YT_8bit_Write_Command(0x04);
   TFT_SSD1963YT_8bit_Write_Command(0x01);//SET Vsync pulse
   TFT_SSD1963YT_8bit_Write_Command(0x00);//SET Vsync pulse start position
   TFT_SSD1963YT_8bit_Write_Command(0xff);

This are the gates...

https://alteraforum.com/forum/attachment.php?attachmentid=13596&stc=1

This are the squematic

https://alteraforum.com/forum/attachment.php?attachmentid=13597&stc=1

And this is my result (seems to works good)

https://alteraforum.com/forum/attachment.php?attachmentid=13598&stc=1

What do you think? Anyone have and advice for me? i am in the correct way?

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Note quite sure what you want? if it works, whats the problem?

    Are you wanting us to comment on the (poor) coding style?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    "Are you wanting us to comment on the (poor) coding style", yes i really want a comment or an idea about my poor coding style or another way to doing that.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Some Points:

    1. Add comments to your code - comments should explain WHY you do something, not WHAT.

    2. Sort the ports out - 1 port per line

    3. One big case statement - why?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    you are right this are a little part of the code with coments

    
    module video_controller (
    input clock ,
    input start  ,                 //not used per now
    input  color_in,      //not used per now
    input  x,                //not used per now
    input  y,               //not used per now 
    input  h,                //not used per now
    input  w,                //not used per now
    output reg  data,
    output reg  latches,
    output  finish,                  //not used per now
    output  color_in_next,      //not used per now
    output reg rst                
    ); 
    reg  i_counter=0;     //start i_counter=0
    localparam  StartCmd=4'b0101; 
    localparam  EndCmd=4'b1111; 
    localparam  StartIdx=4'b0100; 
    localparam  EndIdx=4'b1110; 
    reg  init = 1'b1;	//variable to start sequencial
    always@(posedge clock && init)
    begin
    i_counter<=i_counter+1;		//increment on posedge clock
    //data 8 bits of data bus to external device
    //latches are the clock,cs,write and read this ar params of the external device
    case (i_counter)
    10 :rst=1'b0;			//1 step - reset device
    1000 :rst=1'b1;			//2 step - reset device
    1010 :latches=StartIdx;		//3 step - latches = 0100
    1020 :data=8'h01;               //4 step - send to device = h01
    1030 :latches=EndIdx;		//5 step - latches = 1110	& WAIT of 1000
    2000 :latches=StartIdx;		//3 step - latches = 0100
    2010 :data=8'h01;		//4 step - send to device = h01
    2020 :latches=EndIdx;		//5 step - latches = 1110	& WAIT of 1000
    3000 :latches=StartIdx;		//3 step - latches = 0100
    3010 :data=8'h01;		//4 step - send to device = h01
    3020 :latches=EndIdx;		//5 step - latches = 1110
    4000 :latches=StartIdx;		//3 step - latches = 0100
    4010 :data=8'he0;		//4 step - send to device = he0
    4020 :latches=EndIdx;		//5 step - latches = 1110	& WAIT of 1000
    5000 :latches=StartCmd;		//3 step - latches = 0101
    5010 :data=8'h01;		//4 step - send to device = h01
    5020 :latches=EndCmd;		//5 step - latches = 1111	& WAIT of 1000
    6000 :latches=StartIdx;		//3 step - latches = 0100
    6010 :data=8'he0;		//4 step - send to device = he0
    6020 :latches=EndIdx;		//5 step - latches = 1110
    6030 :latches=StartCmd;		//3 step - latches = 0101
    6040 :data=8'h03;		//4 step - send to device = h03
    6050 :latches=EndCmd;		//5 step - latches = 1111
    

    One big case statement why?.

    Because i need a sequential and timming excecution on ports

    Best Regards