Flip-fl0p 4 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба 1 минуту назад, vladec сказал: В честном I2C сделать "короткое замыкание" нельзя принципиально, поскольку ноль там активный, а единица слабая через подтяжку, тип выходов "открытый коллектор или сток". Ну а если у нас одновременно одно устройство выдает лог.1 а другое устройство придавливает линию к нулю ? Такая ситуация вполне возможна... Например ошибка в прошивке FPGA. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladec 7 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба 1 минуту назад, Flip-fl0p сказал: Ну а если у нас одновременно одно устройство выдает лог.1 а другое устройство придавливает линию к нулю ? Такая ситуация вполне возможна... Например ошибка в прошивке FPGA. Тогда на шине будет обычный стандартный ноль. В "правильной" I2C устройства выдают на шину только нули, а единица формируется исключительно резистивной подтяжкой шины к плюсу питания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба 1 минуту назад, vladec сказал: Тогда на шине будет обычный стандартный ноль. В "правильной" I2C устройства выдают на шину только нули, а единица формируется исключительно резистивной подтяжкой шины к плюсу питания. Именно так. В "правильной" i2c шине все происходит именно так. Но у создателя темы i2c контроллер скачан на просторах интернета. Контроллер не проверен. Я лишь предупреждаю ТС, что если контроллер содержит ошибку - то крайне рискованно запускать тестирование в железе. Тем более в том коде сходу в глаза бросаются некоторые ошибки.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vladec 7 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба 3 минуты назад, Flip-fl0p сказал: Именно так. В "правильной" i2c шине все происходит именно так. Но у создателя темы i2c контроллер скачан на просторах интернета. Контроллер не проверен. Я лишь предупреждаю ТС, что если контроллер содержит ошибку - то крайне рискованно запускать тестирование в железе. Тем более в том коде сходу в глаза бросаются некоторые ошибки.... Ну это если у него неправильно заданы типы выходов шины на ПЛИС, как push-pull. По другому закоротить никак не получится, вот "завесить" или сбить, это элементарно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба Кстати i2c можно же еще попробовать из ip core. мануал Embedded Peripherals IP User Guide Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey87 0 9 ноября, 2018 Опубликовано 9 ноября, 2018 · Жалоба Вот на intel взял исходник: /************************************************************************************************************ I2C to GPIO Port expander. Date: December 21, 2006. ************************************************************************************************************/ `timescale 1us/10ns /* Top module */ module I2C_to_GPIO ( sda, sclk, GPIO_input, GPIO_output); inout sda; // Bidirectional SDA input sclk; // Bidirectional SCLK input [7:0] GPIO_input; output [7:0] GPIO_output; parameter slave_address = 7'h0; // can be changed as per the protocol это для адреса slave? parameter n = 8; reg start_stop; // Indicated if the device has detected a start and is busy in some operation reg start, stop; // Goes high temperarily when a start or stop is detectd reg some_other_device; // to reset start_stop, when the adress on the bus is different from the device address; reg repeat_start; // to reset everything if repeat start is detected. reg write_flag; // to set when write oper begins reg reset; // Used to reset the start , stop registers reg sda_out; // To force the SDA output Low. Remains tristated for sending High Logic. reg done; // To Indicate data transfer done reg [3:0]count; // Down Counter ( 7 to 0 + ack bit ) reg [n-1:0] GPIO_output; // parallel store reg [n-1:0] GPIO_input_reg; // Stores the Values at the input pins before sending to master. reg data_or_address; // high for data, low for address reg read_oper, add_is_matching; // high for master read; high for address matching /********************************************************************************************************/ /* Detecting STOP Condition on the SDA Bus */ always @ (posedge sda or posedge reset) if (reset) begin stop <= 0; end else if (sclk) begin stop <= 1; end /* Detecting START Condition on the SDA Bus */ always @ (negedge sda or posedge reset) if (reset) begin start <= 0; end else if (sclk) begin start <= 1; end /* Tracking START_STOP related status of the device */ always @ (negedge sclk) if (start_stop & start) begin repeat_start <= 1; reset <= 1; end else if (start) begin start_stop <= 1; reset <= 1; repeat_start <= 0; end else if (stop) begin start_stop <= 0; reset <= 1; repeat_start <= 0; end else if (some_other_device) begin start_stop <= 0; repeat_start <= 1; end else begin reset <= 0; repeat_start <= 0; end /***********************************************************************************************************/ /* Counting of bits. First eight bits are data and the last one is ack. */ wire sda_is_ack = count[3] & count [2]; // High for ack , count = 1111 /* Down Counter, 1111 is ack */ always @ (negedge sclk) if (start) begin count <= 4'h7; // it would decreae to 7 on the first pos edge of sclk. end else if (start_stop) begin if (sda_is_ack) begin // count is restored to 7 count <= 4'h7; end else begin count <= count - 4'h1; // count is decremented until zero. end end /***********************************************************************************************************/ /* Taking the Inputs from SDA line and Comparing with Address */это чтение? always @(posedge sclk) if (start_stop) begin if (~sda_is_ack) begin if (~data_or_address | repeat_start) begin if (repeat_start) begin add_is_matching <= 1; // high means matching data_or_address <= 0; // default is address some_other_device <= 0; // High means that device address does not match with SDA data write_flag <= 0; done <= 0; // Low means Transfer is pending end if (count == 7 & sda != slave_address[6]) add_is_matching <= 0; if (count == 6 & sda != slave_address[5]) add_is_matching <= 0; if (count == 5 & sda != slave_address[4]) add_is_matching <= 0; if (count == 4 & sda != slave_address[3]) add_is_matching <= 0; if (count == 3 & sda != slave_address[2]) add_is_matching <= 0; if (count == 2 & sda != slave_address[1]) add_is_matching <= 0; if (count == 1 & sda != slave_address[0]) add_is_matching <= 0; if (count == 0 & ~sda )begin read_oper <= 0; data_or_address <= 1; end else if (count == 0) begin read_oper <= 1; data_or_address <= 1; end end else if (~read_oper & ~done) begin if (count == 7) GPIO_output[7] <= sda; if (count == 6) GPIO_output[6] <= sda; if (count == 5) GPIO_output[5] <= sda; if (count == 4) GPIO_output[4] <= sda; if (count == 3) GPIO_output[3] <= sda; if (count == 2) GPIO_output[2] <= sda; if (count == 1) GPIO_output[1] <= sda; if (count == 0) begin GPIO_output[0] <= sda; done <= 1; end end else begin if (count == 0) done <= 1; end end else begin if (add_is_matching) begin if (read_oper) write_flag <= 1; end else begin data_or_address <= 0; some_other_device <= 1; end end end else begin add_is_matching <= 1; // high means matching data_or_address <= 0; // default is address some_other_device <= 0; write_flag <= 0; done <= 0; end /***********************************************************************************************************/ /* Writing ACK and DATA on the SDA Line*/ wire ack_flag = (count[3]|count[2]|count[1]|count[0]); //becomes low when count is 0 always@(negedge sclk) if (start_stop) begin if (~ack_flag) begin if ( add_is_matching & ~write_flag)begin sda_out <= 1'b0; end else begin sda_out <= 1'bz; end if (read_oper & ~done) GPIO_input_reg <= GPIO_input; end else if (read_oper & data_or_address & ~done) begin if (ack_flag) begin if (~GPIO_input_reg[7]) begin sda_out <= 1'b0; end else begin sda_out <= 1'bz; end GPIO_input_reg <= GPIO_input_reg << 1; end end else begin sda_out <= 1'bz; end end wire sda; assign sda = sda_out; endmodule ................................................................... как с помощью этого кода можно записывать (адрес slave 7'h50) и почему здесь нет тактовой частоты? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 10 ноября, 2018 Опубликовано 10 ноября, 2018 · Жалоба 6 часов назад, Alexey87 сказал: почему здесь нет тактовой частоты Потому что это ведомое (slave) устройство? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 10 ноября, 2018 Опубликовано 10 ноября, 2018 · Жалоба 16 часов назад, Alexey87 сказал: Вот на intel взял исходник: как с помощью этого кода можно записывать (адрес slave 7'h50) и почему здесь нет тактовой частоты? Вы привели отличный пример, каким не должен быть проект на FPGA... Может он и будет работать. Но сбои и ошибки ему гарантированны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AnatolySh 0 22 ноября, 2018 Опубликовано 22 ноября, 2018 · Жалоба On 11/10/2018 at 1:22 AM, Alexey87 said: как с помощью этого кода можно записывать (адрес slave 7'h50) и почему здесь нет тактовой частоты? Вам хочется разбираться с чужими кодами, а не писать свое, как рекомендовали? Взгляните и на мой самописный код, которым я успешно работал с cat24wc256. Но я всё-равно присоединяюсь к вышесказанному и советую вам самому разобраться в вопросе ни на кого, кроме стандартов и datasheet-ов, не глядя. i2c.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey87 0 24 ноября, 2018 Опубликовано 24 ноября, 2018 (изменено) · Жалоба to: AnatolySh. Спасибо за код, на данный момент я уже не пытаюсь разобраться с протоколом i2c, а приступил к базовым основам цифровой схемотехники и уже потом наверное буду пробовать свои силы. С уважением, Алексей. Изменено 24 ноября, 2018 пользователем Alexey87 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 24 ноября, 2018 Опубликовано 24 ноября, 2018 · Жалоба 9 часов назад, Alexey87 сказал: to: AnatolySh. Спасибо за код, на данный момент я уже не пытаюсь разобраться с протоколом i2c, а приступил к базовым основам цифровой схемотехники и уже потом наверное буду пробовать свои силы. С уважением, Алексей. Очень хорошая книга, которая может Вам помочь: Уэйкерли Дж.Ф. Проектирование цифровых устройств. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey87 0 24 ноября, 2018 Опубликовано 24 ноября, 2018 · Жалоба 6 hours ago, Flip-fl0p said: Очень хорошая книга, которая может Вам помочь: Уэйкерли Дж.Ф. Проектирование цифровых устройств. Благодарю Вас, сейчас ещё жду: Токхейм Р. Основы цифровой электроники. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 3 декабря, 2018 Опубликовано 3 декабря, 2018 (изменено) · Жалоба Я свои исходники кастомные более менее обобщил, если будет актуально, отпишитесь, помогу чем смогу. Но лучше конечно самому разобраться, лучше задавайте вопросы по протоколу. Изменено 3 декабря, 2018 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexey87 0 11 января, 2019 Опубликовано 11 января, 2019 (изменено) · Жалоба Здравствуйте, попробовал описать запись по протоколу I2C для EEPROM 24C04 (как я понял реализацию). В архиве, то что получилось. test.rar У меня возникли вопросы: 1. Как правильно инкрементировать значение регистра reg reg[7:0]data = 0; data <= data + 1 или data <= data + 1'b1? 2. Как правильно обнулять значение регистра reg data <= 0 или data <= 8'b0 или data <= 8'b00000000? С уважением, Алексей. p.s. Интересуют варианты реализации для 1 и 2 вопроса. Изменено 11 января, 2019 пользователем Alexey87 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 14 11 января, 2019 Опубликовано 11 января, 2019 · Жалоба 1 час назад, Alexey87 сказал: 1. Как правильно инкрементировать значение регистра reg reg[7:0]data = 0; data <= data + 1 или data <= data + ? Поздравляю вас с выбором Верилога. Можно так и так, но из-за того, что целые числа являются 32-разрядными, то, если вы будете просто писать <= 0 или <= 1, вас будет спамить варнингами о несовпадении разрядностей левой и правой части. Поэтому лучше писать data <= data + 1'b1. Меня, испорченного VHDL'ем, эта лишняя писанина из-за варнинга на пустом месте сильно достаёт. 1 час назад, Alexey87 сказал: data <= 0 или data <= 8'b0 или data <= 8'b00000000? Всё то же самое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться