Jump to content
    

Как соединить два порта inout

А самый простой, надежный, и поддерживающий все нюансы протокола способ - соединить их "соплей" снаружи :) :) Наверняка и на одной половине шины, и на другой, есть резисторы, поэтому подсопливиться туда проблем быть не должно.

Share this post


Link to post
Share on other sites

:a14: Господа огромное спасибо всем ответившим. Сижу леплю. По мере возникновения вопросов буду их задавать .

Share this post


Link to post
Share on other sites

А самый простой, надежный, и поддерживающий все нюансы протокола способ - соединить их "соплей" снаружи :) :) Наверняка и на одной половине шины, и на другой, есть резисторы, поэтому подсопливиться туда проблем быть не должно.

очень бы хотелось, но плата вне зоны досягаемости, боюсь еще даже не появилась на свет, и работать с ней придется по teamviewer'y

 

Вообщем получилась следующая фиговина :biggrin:

post-74507-1408545567.jpg

Share this post


Link to post
Share on other sites

Ну выглядит как-то не очень корректно...

Во первых, на вход контроллера должны идти как SDA1, так и SDA2. Чтобы определить, кто из них инициатор нуля на этой линии. У Вас же идет туда только SDA1.

Во вторых, по идее, не должно быть прямого пути SDA1->SDA2 и SDA2->SDA1. На оба SDA должны идти только сигналы, разрешающие выдачу нуля на выходы, либо запрещающие выходы вообще (выход типа Open Drain). То есть на входе данных тристабильного буфера должен быть жесткий ноль (у Вас - данные с другого SDAx), ну а разрешением управлять от контроллера, тем самым эмулируя Open Drain.

В третьих, для начала, если известно, где мастер, то SCL там не нужна вообще.

Share this post


Link to post
Share on other sites

Может быть вопрос дурацкий, но почему нельзя сделать как на рисунке?

Эту схему заклинит навечно в нуле от первого же нуля на любом SDA по причине наличия 100% положительной обратной связи (в аналоговом смысле этого словосочетания).

Share this post


Link to post
Share on other sites

А самый простой, надежный, и поддерживающий все нюансы протокола способ - соединить их "соплей" снаружи :) :) Наверняка и на одной половине шины, и на другой, есть резисторы, поэтому подсопливиться туда проблем быть не должно.

+1

Share this post


Link to post
Share on other sites

Эту схему заклинит навечно в нуле от первого же нуля на любом SDA по причине наличия 100% положительной обратной связи (в аналоговом смысле этого словосочетания).

 

и у меня почему-то что-то подобное получается. :laughing:

always @(*) begin
    next = 'bx;
    SDA2_output_en = 1'b0;
    SDA1_output_en = 1'b0;
    
    case(state) 
    
        IDLE: begin
            if            ((SDA1_reg[2]) && (!SDA1_reg[1]))  // если на SDA1 1->0
                next = SDA2_OUT_EN;                                     // делаем SDA2 выходом
            else if         ((SDA2_reg[2]) && (!SDA2_reg[1]))     // если на SDA2 1->0
                next = SDA1_OUT_EN;                                     // делаем SDA1 выходом
            else    
                next = IDLE;
        end
        
        SDA2_OUT_EN: begin
            SDA2_output_en = 1'b1;
            if((!SDA1_reg[2]) && (SDA1_reg[1]))                         // ждем переход на SDA1 0->1
                next = IDLE;                                                    // чтобы отпустить SDA2
            else
                next = SDA2_OUT_EN;
            end
            
        SDA1_OUT_EN: begin
            SDA1_output_en = 1'b1;
            if ((!SDA2_reg[2]) && (SDA2_reg[1]))                         // ждем переход на SDA2 0->1
                next = IDLE;                                                     // чтобы отпустить SDA1
            else 
                next = SDA1_OUT_EN;
        end
        
    endcase
end

// drive output signals

assign SDA1 = (SDA1_output_en) ? (1'b0) : (1'bz);
assign SDA2 = (SDA2_output_en) ? (1'b0) : (1'bz);

endmodule

 

в симуляторе работает такое ,а вот в железку не встает . SDA2 всегда 0 .

Share this post


Link to post
Share on other sites

в симуляторе работает такое ,а вот в железку не встает . SDA2 всегда 0 .

И не будет работать. Вам же сказали

можно на достаточно высокой частоте мониторить оба входа-выхода,

Share this post


Link to post
Share on other sites

И не будет работать. Вам же сказали

 

ЭЭэээ , извиняюсь конечно, что не выложил первую часть кода, но я подумал , что она сама собой подразумевающаяся :biggrin:

и захламлсять пространство, ну очень уж не хотелось

вот так , пойдет ? :biggrin:

 

//////////////////////////////////////////////////////////////////////////////////
module I2C_bypassSM(
    input     rst_n,
    input     sys_clk,
    input     SCL_IN,
    inout     SDA1,
    inout     SDA2,
        
    output     SCL_OUT
    );

        
// ----------------------------
// Shifting SDA1 and SDA2 into  
// a sync circuit
// ----------------------------

reg [2:0] SDA1_reg;
reg [2:0] SDA2_reg;

always @(posedge sys_clk) begin
    if(rst) begin
        SDA1_reg <= 0;
        SDA2_reg <= 0;
    end
    else begin
        SDA1_reg <= {SDA1_reg[1:0],SDA1};
        SDA2_reg <= {SDA2_reg[1:0],SDA2};
    end
end

//-----------------------------
// FSM for driving tri-state
// outputs
//-----------------------------
parameter IDLE                 = 2'b00,
                    SDA1_OUT_EN = 2'b01,
                    SDA2_OUT_EN = 2'b10;

reg [1:0]    state, next;
reg             SDA2_output_en;                        // a drive signal for tri-state buffer 
reg             SDA1_output_en;                        // a drive signal for tri-state buffer

always @(posedge sys_clk, posedge rst_n) begin
    if (rst_n) 
        state <= IDLE;
    else
        state <= next;
end

always @(*) begin
    next = 'bx;
    SDA2_output_en = 1'b0;
    SDA1_output_en = 1'b0;
    
    case(state)
    
        IDLE: begin
            if            ((SDA1_reg[2]) && (!SDA1_reg[1]))  // если на SDA1 1->0
                next = SDA2_OUT_EN;                                     // делаем SDA2 выходом
            else if         ((SDA2_reg[2]) && (!SDA2_reg[1]))     // если на SDA2 1->0
                next = SDA1_OUT_EN;                                     // делаем SDA1 выходом
            else    
                next = IDLE;
        end
        
        SDA2_OUT_EN: begin
            SDA2_output_en = 1'b1;
            if((!SDA1_reg[2]) && (SDA1_reg[1]))                         // ждем переход на SDA1 0->1
                next = IDLE;                                                    // чтобы отпустить SDA2
            else
                next = SDA2_OUT_EN;
            end
            
        SDA1_OUT_EN: begin
            SDA1_output_en = 1'b1;
            if ((!SDA2_reg[2]) && (SDA2_reg[1]))                         // ждем переход на SDA2 0->1
                next = IDLE;                                                     // чтобы отпустить SDA1
            else
                next = SDA1_OUT_EN;
        end
        
    endcase
end

// drive output signals

assign SDA1 = (SDA1_output_en) ? (1'b0) : (1'bz);
assign SDA2 = (SDA2_output_en) ? (1'b0) : (1'bz);

endmodule

Share this post


Link to post
Share on other sites

Что-то у Вас там слишком много букв :)

вот как-то так... (писал прямо сюда, поэтому без гарантий, что не наглючил)

 

module SDA_bypass (sda1_in, sda2_in, sda1_out, sda2_out, clk);

input sda1_in, sda2_in, clk;
output sda1_out, sda2_out;

reg [2:0] sda1_reg, sda2_reg;
reg dir;

/* receivers. 1'st stage to avoid metastability, 2'nd - receiver FF, 3'rd - for edge detect*/
always @(posedge clk)
  sda1_reg <= {sda1_reg[1:0], sda1_in};

always @(posedge clk)
  sda2_reg <= {sda2_reg[1:0], sda2_in};

/* direction control */
always @(posedge clk)
  if (sda1_reg[1] && !sda2_reg[1] && sda2_reg[2]) dir <= 1'b1; // sda2 -> sda1
  else if (!sda1_reg[1] && sda1_reg[2] && sda2_reg[1]) dir <= 1'b0; // sda1 -> sda2

/* log. zero output enable signals */
assign sda2_out = !dir & !sda1_reg[1];
assign sda1_out = dir & !sda2_reg[1];

endmodule

 

 

UPD: поправил чуток по мелочи.

Share this post


Link to post
Share on other sites

Что-то у Вас там слишком много букв :)

 

это я просто FSM'ки тренируюсь писать :biggrin:

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...