SM 0 20 августа, 2014 Опубликовано 20 августа, 2014 · Жалоба А самый простой, надежный, и поддерживающий все нюансы протокола способ - соединить их "соплей" снаружи :) :) Наверняка и на одной половине шины, и на другой, есть резисторы, поэтому подсопливиться туда проблем быть не должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
egorman44 0 20 августа, 2014 Опубликовано 20 августа, 2014 · Жалоба :a14: Господа огромное спасибо всем ответившим. Сижу леплю. По мере возникновения вопросов буду их задавать . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
egorman44 0 20 августа, 2014 Опубликовано 20 августа, 2014 · Жалоба А самый простой, надежный, и поддерживающий все нюансы протокола способ - соединить их "соплей" снаружи :) :) Наверняка и на одной половине шины, и на другой, есть резисторы, поэтому подсопливиться туда проблем быть не должно. очень бы хотелось, но плата вне зоны досягаемости, боюсь еще даже не появилась на свет, и работать с ней придется по teamviewer'y Вообщем получилась следующая фиговина Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 20 августа, 2014 Опубликовано 20 августа, 2014 · Жалоба Ну выглядит как-то не очень корректно... Во первых, на вход контроллера должны идти как SDA1, так и SDA2. Чтобы определить, кто из них инициатор нуля на этой линии. У Вас же идет туда только SDA1. Во вторых, по идее, не должно быть прямого пути SDA1->SDA2 и SDA2->SDA1. На оба SDA должны идти только сигналы, разрешающие выдачу нуля на выходы, либо запрещающие выходы вообще (выход типа Open Drain). То есть на входе данных тристабильного буфера должен быть жесткий ноль (у Вас - данные с другого SDAx), ну а разрешением управлять от контроллера, тем самым эмулируя Open Drain. В третьих, для начала, если известно, где мастер, то SCL там не нужна вообще. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
10ff 0 20 августа, 2014 Опубликовано 20 августа, 2014 · Жалоба Может быть вопрос дурацкий, но почему нельзя сделать как на рисунке? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 20 августа, 2014 Опубликовано 20 августа, 2014 · Жалоба Может быть вопрос дурацкий, но почему нельзя сделать как на рисунке? Эту схему заклинит навечно в нуле от первого же нуля на любом SDA по причине наличия 100% положительной обратной связи (в аналоговом смысле этого словосочетания). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eugen_pcad_ru 0 21 августа, 2014 Опубликовано 21 августа, 2014 · Жалоба А самый простой, надежный, и поддерживающий все нюансы протокола способ - соединить их "соплей" снаружи :) :) Наверняка и на одной половине шины, и на другой, есть резисторы, поэтому подсопливиться туда проблем быть не должно. +1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
egorman44 0 22 августа, 2014 Опубликовано 22 августа, 2014 · Жалоба Эту схему заклинит навечно в нуле от первого же нуля на любом 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 . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 22 августа, 2014 Опубликовано 22 августа, 2014 · Жалоба в симуляторе работает такое ,а вот в железку не встает . SDA2 всегда 0 . И не будет работать. Вам же сказали можно на достаточно высокой частоте мониторить оба входа-выхода, Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
egorman44 0 22 августа, 2014 Опубликовано 22 августа, 2014 · Жалоба И не будет работать. Вам же сказали ЭЭэээ , извиняюсь конечно, что не выложил первую часть кода, но я подумал , что она сама собой подразумевающаяся и захламлсять пространство, ну очень уж не хотелось вот так , пойдет ? ////////////////////////////////////////////////////////////////////////////////// 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 22 августа, 2014 Опубликовано 22 августа, 2014 · Жалоба Что-то у Вас там слишком много букв :) вот как-то так... (писал прямо сюда, поэтому без гарантий, что не наглючил) 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: поправил чуток по мелочи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
egorman44 0 22 августа, 2014 Опубликовано 22 августа, 2014 · Жалоба Что-то у Вас там слишком много букв :) это я просто FSM'ки тренируюсь писать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 1 сентября, 2014 Опубликовано 1 сентября, 2014 · Жалоба А что нибудь типа P82B96 снаружи поставить не судьба? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться