Перейти к содержанию
    

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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

post-74507-1408545567.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

+1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эту схему заклинит навечно в нуле от первого же нуля на любом 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 .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

ЭЭэээ , извиняюсь конечно, что не выложил первую часть кода, но я подумал , что она сама собой подразумевающаяся :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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

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: поправил чуток по мелочи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...