Linux: Временное решение ошибки I2C Broadcom.

Созданный на 20 мар. 2013  ·  73Комментарии  ·  Источник: raspberrypi/linux

Broadcom BCM2835 имеет (аппаратную) ошибку в модуле I2C.

BCM плохо реализует "растяжение часов":

Вместо обеспечения минимального "высокого времени" для часов, BCM позволяет часам I2C внутренне работать, и когда приходит время снова перевернуть часы, он проверяет, стали ли часы высоким, и если он низкий, он делает "часы растягиваются". Однако если всего за несколько наносекунд до этой проверки ведомое устройство выпускает тактовый сигнал, указывающий, что он готов к новому тактовому сигналу, тактовый импульс может стать всего 40 нс. (это самый низкий уровень, который я могу измерить, и это, конечно, довольно редко). При тактовой частоте I2C 100 кГц (10 микросекунд) «плохие» моменты для освобождения тактовой частоты составляют 5 микросекунд.

Моим рабам требуется тактовый импульс не менее 500 нс. (что должно быть в десять раз короче, чем то, что мастер должен генерировать, когда он настроен на работу 100 кГц).

Это аппаратная ошибка, с которой мы пока мало что можем сделать. (Совет для тех, кто занимается аппаратным обеспечением: вместо того, чтобы реализовывать растягивание часов таким образом: запретите подсчет счетчика CLOCKDIV, пока часы остаются низкими. Это, вероятно, приведет к увеличению тактового сигнала на несколько быстрых тактов в каждом цикле, но соответствие стандартам значительно улучшится ).

Когда это происходит, BCM отправляет байт с очень коротким первым тактовым импульсом. Тогда ведомое устройство не видит первый тактовый импульс, поэтому, когда в конце этого байта наступает время для подтверждения этого байта, ведомое устройство все еще ожидает 8-го бита. BCM интерпретирует это как «NAK» и прерывает передачу I2C. Однако в этот момент ведомое устройство видит свой 8-й тактовый импульс и выдает «ACK» (переводит линию SDA в низкий уровень). Это, в свою очередь, означает, что BCM не может выдать правильное условие «START» для следующей передачи.

Предлагаемый программный обходной путь для уменьшения воздействия этой аппаратной ошибки: когда передача прерывается из-за «NAK» для байта, выполните один дополнительный тактовый цикл перед STOP для синхронизации ведомого устройства. Вероятно, это нужно делать программно.

Это происходит только в «пути ошибки», когда ведомое устройство не подтверждает байт. Может быть, лучше делать это только тогда, когда это НЕ первый байт передачи, поскольку ошибка не может произойти в первом байте передачи.

Входит ли это программное исправление в драйвер? Да. Это драйвер для оборудования, в котором есть ошибка. Обязанность водителя - заставить это неисправное оборудование работать как можно лучше.

Самый полезный комментарий

Привет hmf2015,
Это не форум. Это баг-трекер. В этом списке комментариев обсуждается ошибка, не имеющая отношения к вашим проблемам. Пожалуйста, обсудите вашу проблему на соответствующем форуме или в службе поддержки. Опять же, мы ценим ваш вопрос: «Может быть, это то же самое? Может быть, мое описание поможет решить эту ошибку?» но теперь мы точно знаем, что то, что вы видите, не имеет отношения, пожалуйста, не «загрязняйте» это обсуждение дальше.

Все 73 Комментарий

Если обходной путь в драйвере позволяет ему лучше работать для большинства пользователей, его следует включить.
У вас есть подходящий патч?

Нет, не сейчас.

1) В драйвер I2C пока не копался. Около года назад я планировал написать это сам, но прежде, чем я дошел до него, это написал кто-то другой. Так что тот, кто уже знаком с этим драйвером, может быть лучше подготовлен для выполнения этого пятиминутного проекта. На знакомство с водителем у меня уйдет как минимум несколько часов.
2) Сначала стоит обсудить это, если вы (и, возможно, другие) согласны с тем, что исправление / обходной путь оправдан.
3) Я просто хотел задокументировать это как «задачу», которую мы не должны забывать ....
4) Может быть, кто-нибудь предложит другое решение.

Говоря об обходных путях: обходное решение также может быть вызвано тем, что линия SDA все еще остается низкой, когда мы пытаемся инициировать новую транзакцию. Это явно "проблемная" ситуация.

Случай «что-то пошло не так» может быть редкостью для «нормальных» случаев. Многие люди будут иметь модуль hardware-i2c на шине I2C. Когда был изобретен I2C, «10us» могло быть «очень коротким» временным интервалом для некоторых микросхем для обработки запросов, поэтому было необходимо растяжение тактовой частоты. В настоящее время любая реализация аппаратного I2C должна уметь обрабатывать «быстрый I2C» до даже быстрее.

Это сочетается с тем, как ребята из atmel реализовали свои асинхронные модули. Вместо того, чтобы модуль работал с внешними часами (i2c-slave или SPI-slave), модуль по-прежнему работает с тактовыми частотами процессора. И он синхронизирует все входящие сигналы, пропуская их через кучу filpflops. Хороший дизайн оборудования. Альтернатива IMHO лучше: запустите модуль от внешних часов и синхронизируйте, когда данные передаются в другой (cpu-) домен часов. Это, например, позволит модулю SPI работать на частоте 20 МГц, даже если процессор работает только на 8.

Так или иначе. Хватит аппаратной болтовни.

Предлагаемое обходное решение: выдать дополнительный тактовый цикл, когда в начале транзакции линия SDA все еще низкая. (он должен начинаться с высокого уровня, чтобы иметь возможность выдать условие «старт»).

Во-первых, я мало знаю о I2C. Я говорил с Гертом и другими о обходных путях.

Есть две известные проблемы с I2C:

  1. Проблема растяжения часов, которую вы описали
  2. Проблема с конечным автоматом I2C при перезапуске

Во-первых, по мнению Герта, не существует надежного обходного пути.
Если ведомое устройство I2C не поддерживает растяжение часов, все в порядке.
Если часы I2C растягиваются на ограниченную величину, то снижение тактовой частоты I2C может избежать проблемы.
Безопасным обходным решением является переключение на немного сбивающий драйвер для ведомых устройств, которые не падают в предыдущих случаях.

Не знаю, сработает ли ваше предложение. Мне было бы интересно узнать, уменьшит ли это проблему или решит ее полностью.

Герт говорит, что у него есть описание ошибки, которую он попытается исправить.

Для 2 в драйвере I2C графического процессора у нас есть код, работающий над проблемой с конечным автоматом:

/***********************************************************
 * Name: i2c_actual_read
 *
 * Arguments:
 *       const I2C_PERIPH_SETUP_T *periph_setup,
         const uint32_t sub_address,
         const uint32_t data_to_read_in_bytes,
         void *data
 *
 * Description: Routine to actually transfer data to the I2C peripheral
 *
 * Returns: int == 0 is success, all other values are failures
 *
 ***********************************************************/
static int32_t i2c_actual_read(  const I2C_PERIPH_SETUP_T *periph_setup,
                                 const I2C_USER_T *user,
                                 const uint32_t sub_address,
                                 const uint32_t read_nbytes,
                                 void *data,
                                 const int using_interrupt)
{
   int32_t rc = -1; /* Fail by default */
   int32_t status = 0;
   int32_t nbytes;

   uint32_t sub;
   uint8_t* read_data = (uint8_t*)data;
   uint32_t data_read = 0;

   if( NULL != periph_setup && NULL != data ) {

      // confirm that the latch is held for this transaction
      assert( i2c_state.periph_latch[ periph_setup->port ] != rtos_latch_unlocked() );

      // -> START
      // -> Slave device address | WRITE
      // <- Ack
      // -> Sub address
      // <- Ack
      // -> Sub address
      // <- Ack
      // -> ReSTART
      // -> Slave device address | READ
      // <- Ack
      // <- Data[0]
      // -> Ack
      // <- Data[1]
      // -> nAck
      // -> STOP

      I2CC_x( periph_setup->port )     = I2CC_EN | I2CC_CLEAR; /* Enable I2C and clear FIFO */
      I2CS_x( periph_setup->port )     = I2CS_ERR | I2CS_DONE | I2CS_CLKT; /* clear ERROR and DONE bits */
      I2CA_x( periph_setup->port )     = periph_setup->device_address;

      sub = sub_address;
      nbytes = periph_setup->sub_address_size_in_bytes;

      if( 0 == nbytes ) {
         /* No subaddress to send - just issue the read */
      } else {
         /*
           See i2c.v: The I2C peripheral samples the values for rw_bit and xfer_count in the IDLE state if start is set.

           We want to generate a ReSTART not a STOP at the end of the TX phase. In order to do that we must
           ensure the state machine goes RACK1 -> RACK2 -> SRSTRT1 (not RACK1 -> RACK2 -> SSTOP1). 

           So, in the RACK2 state when (TX) xfer_count==0 we must therefore have already set, ready to be sampled:
           READ ; rw_bit     <= I2CC bit 0   -- must be "read"
           ST;    start      <= I2CC bit 7   -- must be "Go" in order to not issue STOP
           DLEN;  xfer_count <= I2CDLEN      -- must be equal to our read amount

           The plan to do this is:
           1. Start the sub-add]ress write, but don't let it finish (keep xfer_count > 0)
           2. Populate READ, DLEN and ST in preparation for ReSTART read sequence
           3. Let TX finish (write the rest of the data)
           4. Read back data as it arrives

         */
         assert( nbytes <= 16 );
         I2CDLEN_x( periph_setup->port )  = nbytes;
         I2CC_x( periph_setup->port )    |= I2CC_EN | I2CC_START; /* Begin, latch the WRITE and TX xfer_count values */

         /* Wait for us to leave the idle state */
         while( 0 == ( I2CS_x(periph_setup->port) & (I2CS_TA|I2CS_ERR) ) ) {
            _nop();
         }
      }

      /* Now we can set up the parameters for the read - they don't get considered until the TX xfer_count==0 */
      I2CDLEN_x( periph_setup->port )  = read_nbytes;
      I2CC_x( periph_setup->port )     |= I2CC_EN | I2CC_START | I2CC_READ;

      /* Let the TX complete by providing the sub-address */
      while( nbytes-- ) {
         I2CFIFO_x( periph_setup->port ) = sub & 0xFF; /* No need to check FIFO fullness as sub-address <= 16 bytes long */
         sub >>= 8;
      }

      /* We now care that the transmit portion has completed; the FIFO is shared and we mustn't read out
         any of the data we were planning on writing to the slave! */

      /* Wait for peripheral to get to IDLE or one of the two RX states - this way we *know* TX has completed or hit an error */
      {
         uint32_t state;
         bool_t state_transition_complete;
         bool_t error_detected;
         do { 
            state = (I2CS_x( periph_setup->port ) & 0xf0000000) >> 28;
            state_transition_complete = ((state == 0) || (state == 4) || (state == 5));
            error_detected = (I2CS_x(periph_setup->port) & (I2CS_ERR | I2CS_CLKT)) != 0;
         } while(!state_transition_complete && !error_detected);

         if (error_detected) {
            /* Clean up, and disable I2C */
            I2CC_x( periph_setup->port ) &= ~(I2CC_INTD | I2CC_INTR);
            I2CC_x( periph_setup->port ) &= ~(I2CC_START | I2CC_READ);
            I2CS_x( periph_setup->port ) = I2CS_CLKT | I2CS_ERR | I2CS_DONE;
            I2CC_x( periph_setup->port ) |= I2CC_CLEAR;
            I2CC_x( periph_setup->port ) = 0;
            return -1;
         }
      }

      if (using_interrupt)
      {
         /* Wait for interrupt to complete. */
         i2c_state.active_buffer[periph_setup->port] = data;
         i2c_state.active_buffer_length[periph_setup->port] = read_nbytes;
         i2c_state.active_buffer_offset[periph_setup->port] = 0;
         i2c_state.pending_transfer[periph_setup->port] = I2C_PENDING_TRANSFER_READ;
         RTOS_LATCH_T latch = rtos_latch_locked();
         i2c_state.pending_latch[periph_setup->port] = &latch;

         /* Enable interrupt. */
         I2CC_x( periph_setup->port ) |= I2CC_INTD | I2CC_INTR;

         rtos_latch_get (&latch);

         i2c_state.pending_latch[periph_setup->port] = NULL;
         data_read = i2c_state.active_buffer_offset[periph_setup->port];

         rc = (data_read == read_nbytes) ? 0 : -1;
      }
      else
      {
         uint32_t time_now = 0;

         /* Loop until we've read all our data or failed. */
         while( 0 == ( I2CS_x(periph_setup->port) & (I2CS_TA|I2CS_ERR|I2CS_DONE) ) ) {
            _nop();
         }

         /* Wait for some data to arrive - we should wait, at most, I2C_TIMEOUT_IN_USECS for data to arrive every time we start waiting */
         time_now = i2c_state.systimer_driver->get_time_in_usecs( i2c_state.systimer_handle );
         while( ((i2c_state.systimer_driver->get_time_in_usecs( i2c_state.systimer_handle ) - time_now) < I2C_TIMEOUT_IN_USECS)
                && ( data_read < read_nbytes )
                && !(I2CS_x( periph_setup->port ) & I2CS_ERR) ) 
         {
            if (I2CS_x( periph_setup->port ) & I2CS_RXD) 
            {
               read_data[ data_read ] = I2CFIFO_x( periph_setup->port );
               data_read++;
               time_now = i2c_state.systimer_driver->get_time_in_usecs( i2c_state.systimer_handle  );
            }
         }

         if( (data_read != read_nbytes) /* Did we read all the data we asked for? */
             || ( (read_nbytes - data_read) != I2CDLEN_x( periph_setup->port ) ) /* Has DLEN decremented? */
             || ( 0 != (I2CS_x( periph_setup->port ) & I2CS_ERR) ) ) { /* Are there any errors? */
            rc = -1;
         } else {
            while( I2CS_DONE != (I2CS_x(periph_setup->port) & I2CS_DONE) ); /* Wait for the peripheral */
            rc = 0;
         }
      }

      /* Clean up, and disable I2C */
      I2CC_x( periph_setup->port ) &= ~(I2CC_INTD | I2CC_INTR);
      if(I2CS_x( periph_setup->port ) & I2CS_ERR) {
         //Wait for it to be idle
         while(I2CS_x( periph_setup->port ) & I2CS_TA)
            _nop();
      }
      I2CS_x( periph_setup->port ) = I2CS_ERR | I2CS_DONE;
      //Finally disable the I2C
      I2CC_x( periph_setup->port ) = 0x0;
   }

   if( !user->skip_asserts ) {
      assert( rc >= 0 );
      _nop();
   }

   return rc;
}      

Я не уверен, сталкиваются ли люди с этой проблемой, но вставленное может быть полезно, если вы это сделаете.

Полностью устранить эту аппаратную ошибку невозможно.

Когда это происходит, ведущий и ведомый расходятся во мнениях относительно количества тактов. Следовательно, данные, интерпретируемые ведомым устройством, и данные, предназначенные для ведущего устройства (= raspberry pi = драйвер / приложение), различаются. Возможно, вы записываете в какой-то регистр полностью поддельное значение. Сильно раздражает.

Предлагаемый мной обходной путь, по крайней мере, заставит работать следующую транзакцию. Воздействие будет уменьшено вдвое: только одна транзакция будет неудачной вместо двух. Это не устранило бы проблему.

Если ведомое устройство I2C не поддерживает растяжение часов, все в порядке.

Если ведомому устройству I2C не требуется растягивание часов ....

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

Да. У меня есть 10 устройств «в поле» в одном месте. Очевидно, тактовая частота (RC-часы) трех модулей различается таким образом, что они завершают работу с растягиванием тактовой частоты точно в неподходящий момент. Снижение тактовой частоты устранило проблемы этих модулей.

Если задержка растяжения часов НЕ фиксирована, а, скажем, изменяется более чем на 5 микросекунд, существует более или менее статистический шанс решить проблему. В моем случае ведомому устройству требуется 0,25 микросекунды ширины тактового сигнала. Таким образом, растяжение часов заканчивается в 5% времени, предшествующем моменту изменения часов для BCM, тогда все идет не так. Таким образом, в этом случае примерно 1 из 20 переводов будет ошибкой. (В спецификациях указано минимум 250 нс для тактового импульса. На самом деле это не означает, что его не будет видно, если он короче. Я думаю, что шансы увидеть его линейно возрастают от 100% при> 250 нс до 0% при < 125нс.)

Вчера я растягивал период растяжения часов таким образом, чтобы он упал примерно на отметку 2,5 микросекунды в 5-микросекундном окне возможностей. Если бы я нацелился на начало окна и мои часы RC бегали немного быстрее, я бы нажал «0», что вызовет ошибку. Если я стремлюсь к 5, то же самое. Так что теперь я целюсь посередине, подальше от плохих мест. Но измените частоту I2C на 80 кГц, и BAM, я нацеливаюсь прямо на чувствительную точку ... (и если этого не произойдет с 80 кГц, это произойдет с некоторым значением от 80 до 100).

Вот описание Герта ошибки I2C:
https://dl.dropbox.com/u/3669512/2835_I2C%20interface.pdf

Ха-ха! Точно так же я настроил свою тестовую доску. Я отрезал дорожку SCL и установил туда перемычку 0,1 дюйма. Пока я не проводил измерения, там есть нормальная перемычка или гнездовой разъем с резистором 100 Ом, когда я работаю.

Я не думаю, что это происходит только в первые часы. Это означало бы, что я мог бы обойти проблему, либо НЕ растягивая тактовую частоту вообще (как, вероятно, делает большинство аппаратных чипов I2C), либо заставляя тактовую частоту длиться как минимум полный цикл.

Я оснастил свой подчиненный код i2c таким образом, что могу заставить растяжение тактовой частоты изменяться с шагом 0,5 микросекунды. Я могу приказать ему изменить растяжение часов на XXX по I2C, а затем он будет работать так же в течение 50 миллисекунд, прежде чем вернуться к значениям по умолчанию. (в случае, если это не сработает, нам нужно, чтобы он снова заработал. Таким образом, я могу быстро просканировать весь диапазон значений этих настроек, одновременно отслеживая линии SDA и SCL с помощью логического анализатора. Отправка «использовать задержку XXX», а затем отправка сообщения занимает 25 миллисекунд. Затем для увеличения счетчика в сценарии и отправки "следующей задержки" сценарий оболочки занимает около 100 мсек. Таким образом, я могу просканировать 100 возможных значений примерно за 10 секунд.

Я видел, как ошибка возникает при более длительных задержках. Итак, теория: «это происходит только в первый раз» неверна.

Что касается «сверхэффективного» обработчика прерываний: да, я тоже могу это сделать. Дело в том, что функция растягивания часов позволяет мне поместить код «обработать этот байт» в процедуру прерывания и не беспокоиться о том, что это займет несколько микросекунд или несколько миллисекунд. Теоретически растяжение часов гарантирует, что мастер будет ждать, пока я закончу обработку этого байта, прежде чем продолжить работу со следующим. Этот план полностью нарушен ошибкой в ​​2835. Теперь я просто останавливаю растяжение часов, а затем надеюсь закончить обработку байта в следующие 70 микросекунд.

Мне нужно «подсчитывать циклы», чтобы нацелиться на середину 5-микросекундных полутонов, чтобы освободить время от растяжения часов. Если бы я нацелился на запуск (чтобы вызвать высокий период тактовой частоты 4,9 микросекунды), часы на моем ведомом устройстве могли бы работать на несколько процентов быстрее и вызвать ошибку срабатывания на полцикла раньше. Таким образом, оба конца полусинхронного цикла опасны, я должен стремиться к короткому, но достаточному тактовому циклу.

Изменение в модуле, ИМХО, простое: когда SCL "приводится в высокий уровень" (т. Е. Не работает вообще), остановите основные часы модуля I2C. Это имеет побочный эффект, позволяя использовать гораздо более длинные шины I2C, потому что автоматическое растяжение тактовой частоты происходит, когда емкость шины выше спецификации.

Спасибо за попытку помочь, iz8mbw, но они не имеют ничего общего с этой (аппаратной) ошибкой.

Я измерил свою частоту I2C, и она составила 100 кГц, что, по мнению водителя, должно быть. У драйвера есть объект «источник тактовых импульсов», который он запрашивает для частоты и использует это. Я еще не настроил драйвер для вывода частоты.

Просто для информации для людей, которые хотят ВИДЕТЬ ошибку в действии, у меня есть некоторые «доказательства» в виде дампа логического анализатора.
Хм, я могу прикрепить изображения, но не бинарный дамп ЛА. Это здесь: http://prive.bitwizard.nl/LA_with_bug_scan_50_to_100_microseconds_delay.bin.gz

На изображении LA_with_bug_shot1.png вы увидите короткий всплеск активности: «установить задержку на XXX», затем небольшой всплеск, который пытается записать около 10 байтов, но прерывается из-за NACK. Справа вы видите правильный 10-байтовый пакет. Линия SDA остается на низком уровне до следующего пакета, который не выровнен (все биты сдвинуты, и в моем ведомом устройстве счетчик «xth-byte-in-packet» не был сброшен из-за несуществующего начального условия в начале этого пакета. .

На изображении LA_with_bug_shot2.png я увеличил масштаб до участка, в котором происходит короткий импульс. Это самый длинный импульс, который я когда-либо видел: 290 нс. (Выше спецификации Atmel!)
LA_with_bug_shot1
LA_with_bug_shot2

О, так вот откуда это взялось!

У меня есть проект, которым я пытаюсь управлять с помощью I2C с Raspberry Pi, и я, честно говоря, близок к тому, чтобы просто сдаться и либо переключиться на beagleboard, либо заставить Pi разговаривать с FPGA через SPI, который затем делает вещи I2C .

У меня есть доска по почте, которая должна это делать (ожидаемая доставка: завтра). Разъем SPI, разъем I2C. Было бы неплохо попробовать с этой платой. Отправьте мне электронное письмо, если вы хотите быть в курсе.

Текущая ситуация: я вижу поведение, совместимое с поведением Герта: «только первый цикл может пойти не так», когда ведомое устройство является ATMEGA, и я вижу ошибку в полной мере, когда ведомое устройство является одним из моих ATTINY.

Вот проверенные мной задержки:
i2c_delays_atmega
и самый короткий импульс SCL, наблюдаемый во время этого тестового сеанса, составил 4,5 микросекунды.

Теперь тестирование с ведомым устройством attiny, проверенные задержки для ACK:
i2c_delays_attiny

и минимальная ширина импульса 41 нс (мое разрешение измерения):
i2c_delays_attiny2

Ах. Нашел! Кажется, что тактовое растяжение перед ACK байта "опасно", но тактовое растяжение ПОСЛЕ ACK нормально .....

Я и другие, безусловно, сталкиваемся с проблемой повторного запуска. У меня есть взлом пользовательского пространства на http://cpansearch.perl.org/src/MDOOTSON/HiPi-0.26/BCM2835.xs в proc hipi_i2c_read_register_rs. Кажется, это работает для пользователей, которые сообщили, что пробовали это или использовали код C (хотя это всего 5 человек), хотя я не понял правильно, как определить, что этап TX завершен. Полагаю, мне нужно научиться компилировать модули ядра и запускать существующие тесты для кода выше.

Не могли бы мы просто заставить ядро ​​игнорировать оборудование I2C и использовать I2C на основе битбэджинга на основе GPIO на тех же контактах? Я думаю, что накладные расходы для этого будут более приемлемыми, чем ошибки в самом оборудовании.

Какие накладные расходы вы ожидаете? Текущий драйвер по умолчанию использует частоту 100 кГц. Таким образом, чтение 10 байтов с промежуточного датчика i2c занимает около 1 мс. Если вы используете битбэнг, вы, вероятно, все это время будете перемешивать циклы процессора ...

Я бы предпочел, чтобы драйвер опционально поддерживал битбэнгинг i2c через параметр модуля (или, может быть, отдельный модуль, если это удобнее).

Многие устройства не используют растяжение тактовой частоты (или растяжение тактовой частоты на ограниченную величину, чтобы можно было правильно работать на пониженной скорости), поэтому аппаратный драйвер I2C все же предпочтительнее в этих случаях.

Само ядро ​​имеет драйвер для побитового I2C на выводах GPIO, этот драйвер имеет гораздо меньшие накладные расходы, чем побитовый бит из пользовательского пространства, и предоставляет тот же API, что и аппаратные драйверы I2C. Я предлагаю скомпилировать как этот драйвер, так и аппаратный драйвер I2C в виде модулей, а затем загрузить аппаратный драйвер по умолчанию.

@Ferroin
Вы используете драйвер I2C с битбэнгом на Pi?
Какие параметры .config вы добавили для его создания? Есть ли исходные патчи?
Что вы делаете, чтобы выбрать драйвер для использования (modprobe? Different / dev / devices?)

Я не использовал драйвер на Pi, но у меня есть друг, который успешно использует его на BeagleBoard.
Параметр конфигурации - I2C_GPIO.
Если бы и этот драйвер, и драйвер broadcom были настроены как модули, выбор драйвера был бы таким же простым, как загрузка модуля ядра.
Модулю GPIO нужны параметры, чтобы указать, какие GPIO использовать в качестве SDA и SCL, я не знаю, каковы параметры, но на основе не очень хорошо документированного источника в dirvers / i2c / busses / i2c-gpio.c, похоже, что подходящими параметрами являются sda = X scl = Y, где X и Y - контакты, которые вы можете использовать.

Сам модуль i2c-gpio не предоставляет возможности передавать ему параметры. Поэтому вам нужен другой модуль, который регистрирует данные платформы и настраивает хотя бы номер шины, контакты SDA и SCL. Я написал доказательство концепции такого модуля, и он даже работал на контактах 0 и 1, но без загруженного i2c-bcm2708 (pcf8574 был обнаружен i2cdetect, я смог запустить какой-то светодиод с модулем gpio-pcf857x). Но потом я сжег свой pcf8574 при смене контактов (а других чипов i2c сейчас у меня нет), поэтому я не смог его проверить. Вот код

@kadamsi
Может оказаться полезным создание параметров модуля sda_pin / scl_pin. Как и запрос на перенос.
Может ли кто-нибудь подтвердить, что это работает для них?

Это менее тривиально, чем кажется: предполагается, что структура данных платформы будет полностью передана.

С другой стороны, платформа не диктует, какие GPIO вы собираетесь использовать сегодня, поэтому работа над ее изменением звучит разумно. (обычно в данных платформы указано: «Как / этот / компьютер подключен».)

@popcornmix
Планирую сделать их настраиваемыми, просто вчера не хватило времени. Я также хотел бы, чтобы можно было создавать более одной шины за раз. Может быть, динамически, например файлы GPIOS export и unexport sysfs (но я не уверен, можно ли чисто экспортировать такую ​​шину)? О, и я нашел еще один pcf8574 и смог подтвердить, что он хорошо работает также на разных выводах GPIO, когда используются внешние подтягивающие резисторы. К сожалению, у меня нет более сложных устройств I²C для тестирования. Так вы заинтересованы в предоставлении такого модуля в дереве ядра по умолчанию?

@kadamski
У меня нет настройки для тестирования таких модулей. Однако любые аппаратные функции, которые предоставляет чип (например, I2C), должны иметь драйверы ядра, чтобы их могло использовать большее количество людей. Если в оборудовании I2C есть ошибки, которые не позволяют людям использовать определенные периферийные устройства, то альтернативная альтернатива звучит стоящей.

Итак, если вы создаете новый драйвер, который выглядит безобидным для людей, не использующих его (т.е. построенный как модуль и не имеющий ничего, пока не будет загружен), и есть некоторые доказательства (например, некоторые подтверждающие отчеты пользователей), что он работает правильно, тогда я с радостью приму пиар.

Было ли исправлено HW на BCM2837 (в RPi 3)?

Я думаю: нет. Но у меня, наверное, нет времени сегодня это проверять.

BCM2837 I2C без изменений.

Это прискорбно, но спасибо за информацию.

это очень раздражает.

Я согласен. Есть ли у кого-нибудь ссылка на ошибку BCM2837 или подобное, в которой говорится, что проблема все еще существует? Было бы удобно, когда нам нужно сообщить новости. Или @ P33M , может быть, вас можно назвать авторитетным

Он авторитетный, но на Broadcom не работает.

Это хорошо. Но я уже погуглил, и кроме того, что P33M является M33P где-то еще, изо всех сил пытаюсь найти идентификатор, который я могу с пользой передать. Это нормально, но означает, что он не лучший источник для цитирования. :-) Так что ссылка на опечатку будет кстати.

@ P33M работает с Raspberry Pi. Вы можете считать то, что он говорит, авторитетным.

Не думаю, что есть список исправлений, наверное, должен быть. Я оставил его
подтвердить его личность или нет!

15 марта 2016 года в 14:30 RalphCorderoy [email protected] написал:

Это хорошо. Но я уже гуглил, и кроме P33M это M33P
в другом месте, изо всех сил пытаюсь найти идентификатор, который я мог бы передать. Что нормально,
но значит, он не лучший источник для цитирования. :-) Таким образом, ссылка на опечатку будет
удобно.

-
Вы получили это, потому что оставили комментарий.
Ответьте на это письмо напрямую или просмотрите его на GitHub:
https://github.com/raspberrypi/linux/issues/254#issuecomment -196845789

@RalphCorderoy Я сотрудник Raspberry Pi (trading) Ltd. Мой ответ является авторитетным.

@ P33M , Та,

Это влияет на проект, над которым я работаю. К счастью, у меня есть полный контроль над прошивкой ведомого устройства, и я смог добавить обходной путь, добавив дополнительную задержку на половину периода (тактовую задержку) в мои ответы, которая пропускает плохое поведение.

Хороший анализ проблемы можно найти на сайте advamation.com .

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

Я только что подписался на эту проблему, так как я также столкнулся с ней в продукте, который разрабатываю.
который использует i2c между AVR и Pi. Теперь мне нужно это переосмыслить.
Кто-нибудь использовал какую-нибудь надежную форму i2c bit banging?

@ mwilliams03 , возможно, вас заинтересует этот проект , в котором я успешно установил связь I2C с частотой 100 и 400 кГц между Raspberry Pi и AVR. Я не использую бит-бэнг, а вместо этого использую аппаратную поддержку I2C и вставляю задержки в ключевых точках. Оказалось, что AVR достаточно медленный, поэтому на частоте 400 кГц никаких дополнительных задержек не требуется.

В частности, вот информация о проблемах I2C . Также обратите внимание, что у модуля TWI AVR есть проблема, препятствующая быстрому чтению .

спасибо @ pdg137 , я попробовал, и с первого операций чтения без ошибок и все еще продолжается.

@rewolff похоже, что проблема решена. В этом случае закройте эту проблему.

А теперь .... добавить переключатель уровня и удлинитель 40см .. Тогда он работает? Скорее всего, это вызывает достаточную задержку на "верхней" стороне сигналов, и внезапно ошибка появляется снова.

Насколько я могу судить, Broadcom и сотрудники все еще думают, что эта ошибка ограничена ПЕРВЫМИ 5 микросекундами (фактически полутона) после последнего бита байта. тогда просто добавление 10 микросекунд перенесет ситуацию на два полутона дальше, и проблем не должно быть. В своем тестировании я обнаружил "плохие" моменты, когда часы не растягиваются каждые 5 микросекунд.

Из-за симметрии между SPI и I2C в моем коде AVR проще, если следующий байт данных «вычисляется» в прерывании «следующие данные» .... (я показываю интерфейс, в котором продолжение чтения разрешено, поэтому 16-байтовый буфер не всегда хватает.).

Я не уверен.

У меня возникают проблемы с SMBus между Respberry Pi и ATMEGA 324PA. Могут ли они быть связаны с этой проблемой? https://stackoverflow.com/questions/39274784/talking-smbus-between-raspberr-pi-and-atmega-324pa-avr-not-clock-stretching

Насколько я могу судить, Broadcom и сотрудники все еще думают, что эта ошибка ограничена ПЕРВЫМИ 5 микросекундами (фактически полутона) после последнего бита байта.

@rewolff : Я должен согласиться с сотрудниками Broadcom. В моих тестах с Raspberry Pi 3 и I2C 100 кГц (который замедляется до 62 кГц при дросселировании процессора) я получаю результаты, аналогичные анимации с сайта advamation.com . Получаете ли вы экспериментальные результаты, которые отличаются от этой анимации, или анимации недостаточно, чтобы убедить вас?

Анимация кажется звуковой. Однако это не соответствует моему опыту. Может мне стоит устроить тест. Может потребоваться время. Он занят другим делом.

Но если бы это было так, то просто "usleep (10)" в моей программе обработки прерывания (с аппаратным растяжением часов) обычно помогло бы и не заблокировалось. Я почти уверен, что это не так. :-(

@rewolff : Я видел, как на Raspberry Pi 3

Можно ли включить модуль i2c-gpio-param @kadamski в ядро ​​Raspberry Pi? Я могу подтвердить, что этот подход, похоже, довольно хорошо работает для моего приложения (подчиненное устройство I2C программного обеспечения AVR), и несколько громоздко устанавливать необходимые заголовки для ядра малины, поэтому было бы здорово, если бы он был доступен.

Это также было бы хорошим обходным путем для устранения ошибки HW, лежащей в основе всей этой проблемы.

@onnokort Вы имеете в виду, что оверлей i2c-gpio присутствует в текущих ядрах с ноября 2015 года? https://github.com/raspberrypi/linux/blob/rpi-4.4.y/arch/arm/boot/dts/overlays/i2c-gpio-overlay.dts
Из README для оверлеев:

Name:   i2c-gpio
Info:   Adds support for software i2c controller on gpio pins
Load:   dtoverlay=i2c-gpio,<param>=<val>
Params: i2c_gpio_sda            GPIO used for I2C data (default "23")

        i2c_gpio_scl            GPIO used for I2C clock (default "24")

        i2c_gpio_delay_us       Clock delay in microseconds
                                (default "2" = ~100kHz)

@ 6by9 : Отлично, спасибо, сегодня узнал что-то новое. Я еще не тестировал это, но да, это выглядит именно так, как я искал (и нашел в i2c-gpio-param).

@popcornmix @ 6by9 Это можно закрыть? Прошло довольно много времени, и материал dt param из моего чтения кажется достойным вариантом.

Рекомендуемый обходной путь для устройств, которые определенно не работают с нашим оборудованием I2C, - использовать оверлей i2c-gpio, который выводит битовые биты.

В противном случае расширение тактовой частоты в фазе ACK адреса поддерживается восходящим драйвером.

Дорогие все, сегодня я протестировал BNO055 в пакете GY-955 из Восточной Азии, который ведет себя очень некрасиво на частоте 100_000 Гц с Pi 2B (BMC2835). Для тестов я изменил частоту шины I2C с 50_000 на 400_000 Гц и обнаружил проблемы на 100_000 Гц, но для 50_000, 85_000, 115_000 и 125_000 Гц код от Adafruit (Adafruit_Python_BNO055) отлично работает с соединением I2C, 150_000 Hz кажется слишком быстрым для BNO055, работает, но значения иногда неверны. Признаюсь, я не проверял частоту осциллографом, я только считал файл / sys / class / i2c-adapter / i2c-1 / of_node / clock-frequency, поэтому некоторая неопределенность остается открытой. Теперь я начинаю реализовывать полный интерфейс к BNO055 в ADA.
Facit: Аппаратная ошибка в обработке BMC I2C появляется только при 100_000 Гц, это необходимо подтвердить.

Просто к вашему сведению, аппаратная ошибка возникает, когда ведомое устройство выполняет растягивание часов и освобождает линию SCL после периодов тактовых импульсов I2C от 0,9 до 0,999. Линия начнет подниматься, и оборудование пи скажет: О, он не растягивал тактовую частоту, поэтому я могу обеспечить следующий тактовый импульс, снова установив тактовую линию на низкий уровень.

Ошибка возникает, когда время, оставшееся в тактовом периоде, достаточно для того, чтобы линия clk прошла порог "HIGH" для малины, но не для подчиненных устройств ИЛИ когда подчиненное устройство имеет фильтрацию шума и считает высокий уровень в течение <x% времени нормальный цикл I2C глюк.

Это происходит не «только на частоте 100 кГц», но также и на многих других частотах, за исключением того, что время отклика ведомого устройства должно иметь другое значение.

Предположим, что тактовая частота составляет 100 кГц, поэтому нормальный цикл будет иметь высокий 5 мкс и низкий 5 мкс. Теперь предположим, что в t = 0 пи начинает последний тактовый цикл, переводя тактовую линию в низкий уровень. В момент t = 5us пи высвобождает тактовый сигнал, но ведомое устройство все еще занято и поддерживает низкий уровень тактового сигнала. При t = 9us ведомое устройство готово и выпускает тактовый сигнал. При t = 10 мкс пи посмотрит на тактовый сигнал и подумает: «Хорошо, часы не растягиваются, так что продолжайте», и он снова сбрасывает тактовый сигнал на низкий уровень. Синхронизирующий сигнал теперь имеет высокий уровень только в течение 1 мкс (немного меньше из-за емкости и постоянной времени подтягивающих резисторов) и может быть не замечен ведомым устройством. Теперь другое устройство становится готовым не через 9 микросекунд, а через 10,5. Теперь на частоте 100 кГц pi будет видеть «все еще низкий, тактовая частота растягивается, подождите еще 5 микросекунд. Теперь мы получим тактовый импульс 4,5 микросекунды, и все будет работать. Но запустите это устройство на частоте 90 кГц, и у него возникнут проблемы. Теперь pi будет смотреть на 11 микросекунд с самого начала, а тактовый сигнал будет высоким менее микросекунды -> Проблемы.

Люди, которые жалуются на это, НЕ те, у кого есть другие устройства. Они работают на 100 кГц по умолчанию. Но ошибка все еще очень реальна и могла бы возникнуть на этих устройствах просто на других скоростях шины, чем те устройства, которые есть у вас и меня.

Спасибо за ответ, он очень хорошо объясняет, почему я получил надежную передачу на выбранных мной частотах:
при 100_000 Гц проблемы возникают в период от 9 до 9,99 мкс
при 85_000 Гц проблемы начинаются с 1_000_000 / 85_000 * .9 = 10,59 мкс> 9,99 с, поэтому растяжение тактовой частоты, я полагаю, игнорируется, для всех частот ниже 85_000 Гц начальная точка проблем выше 10,59 мкс .
при 115_000 Гц цикл шины составляет 1_000_000 / 125_000 = 8,7 мкс <9 мкс, поэтому растяжение тактовой частоты определяется правильно, для всех частот выше 115_000 Гц цикл шины составляет менее 8,7 мкс.
Поэтому, когда у меня возникают проблемы, я могу рассчитать нужную мне частоту.
(Прочитал информацию на http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html,
было отмечено .5 вместо .9 точки).

Хорошо. Это зависит от того, что ваше ведомое устройство определяет как действительный тактовый сигнал. И сколько задержки вносит RC в вашем автобусе. В моем случае AVR, который я использую в качестве ведомого, считает, что импульсы менее двух тактовых циклов являются ошибкой. При внутренней частоте RC-генератора 8 МГц (+/- 10% !!!) импульс должен быть не менее 250 нс для обнаружения. Спецификации I2C требуют 5 микросекунд, поэтому существует 20-кратный «запас» между тем, что официально требуется, и тем, что больше не работает.

Сначала я подумал, что увеличу тактовую частоту в моем ведомом устройстве, скажем, на 12 мкс. Это работает до тех пор, пока емкость шины не добавит достаточно задержки, чтобы снова вызвать проблему. Так что обойти это очень сложно. Раздражает необходимость говорить своим клиентам не использовать стандартный 100 кГц i2c.

Извините, но мне потребовалось время, чтобы написать полный сценарий реализации и тестирования.
Благодарю вас за всю информацию, которую вы мне дали, она была очень полезной.
Мой тестовый сценарий состоит из двух MEMS (BNO055 упакован как GY-055, MPU9255 упакован как MPU-9250/6500, в регистре WHO_AM_I указано MPU9255) и 1 расширителя GPIO PCF 8574 (упакованный PCF 8574).
Тактовая частота I2C на Pi (2b) была установлена ​​на 125 кГц, что подтверждено чтением / sys / class / i2c-adapter / i2c-1 / of_node / clock-frequency.
Мой код запускается 100 раз, считывая данные из MEMS и записывая данные для PCF с задержкой 0,1 сек.
Результат:

  • Инициализация MEMS прошла успешно.
  • Чтение данных MEMS по шине I2C было успешным во всех циклах.
  • Запись данных в PCF по шине I2C прошла успешно во всех циклах.

Следовательно, MEMS и PCF принимают частоту выше стандартных 100 кГц.
В старом окружении связь с AVR осуществляется через последовательную линию, во втором случае связь будет осуществляться через USB, но это не закончено, на самом деле я споткнулся о проблемах шины I2C, вызванных BNO055, но я думаю для своей среды я нашел обходной путь для Pi 2b и надеюсь, что он будет работать и с Pi 3, это следующий тест. И затем мне нужно интегрировать 2 других MEMS, 1 VL53L0X и 1 BME280, я надеюсь, что он будет работать с новой частотой, а емкость шины примет все эти элементы.

Сейчас я играю с этой проблемой на RPi 3 Model B +, и я вижу результаты, отличные от описанных в статье Advamation. Кремний недавно не обновляли, не так ли?

Вкратце, кажется, что все работает, если я растягиваю на read-preACK, write-preACK или write-postACK; единственный раз, когда мне нужно быть уверенным, что я растянул либо долго, либо совсем не растянул, это read-postACK. Однако мне все еще нужно очистить свой эксперимент, прежде чем я смогу сказать что-нибудь определенное.

Во-первых, примечание о терминологии. В статье Advamation говорится:

Итак, I2C с Raspberry Pi работает, только если
ведомое устройство вообще не использует растягивание часов, или
ведомое устройство растягивает часы только в конце / непосредственно после фазы I2C-read-ACK (после чтения ACK / NACK), но затем более чем на 0,5 такта.

Термин «I2C-чтение-ACK-фаза» кажется несколько двусмысленным. Если это команда чтения I2C (т. Е. Установлен бит постадреса R / W sl), ведомое устройство будет записывать бит A̅C̅K̅, а не читать его, в отличие от скобок. Когда я говорю здесь "read-postACK", я имею в виду, что бит R / W̅ был установлен сразу после адреса (и, предположительно, не изменен протоколом, как это делает SMBus), поэтому ведомое устройство только что записало свой ответ A̅C̅K̅.

Как уже упоминалось здесь, кажется, что если RPi определяет, что SCL удерживается на низком уровне ведомым устройством, он задерживает свои внутренние часы SCL на один полупериод (5 мкс). Ошибка возникает, если ведомое устройство удерживает низкий уровень SCL в течение _почти_ одного полупериода. Если это произойдет, то RPi все равно будет позволять SCL повышаться, а затем сразу же понижать его, когда срабатывают его часы SCL. Это приводит к прерывистому тактовому импульсу, который некоторые устройства могут воспринимать как импульс, а другие - нет. (Для справки: спецификация I2C подразумевает номинальное время высокого уровня SCL 5 мкс и устанавливает минимальное время 4,0 мкс при 100 кГц, что является скоростью по умолчанию для интерфейса I2C RPi.)

В моих экспериментах на этапах read-preACK, write-preACK и write-postACK RPi гарантировал, что максимальное допустимое время SCL составляет 4 мкс или около того. Казалось, что в этих фазах он готов вернуть свои часы SCL. Я подозреваю, что RPi произвел выборку линии SCL вскоре после того, как он освободил ее, и если SCL все еще был низким, он сдвинул свои часы SCL на половину фазы.

Тем не менее, в фазе read-postACK я действительно видел, что RPi будет излучать короткие тактовые импульсы (<4 мкс, часто 2 мкс или меньше), если линия SCL удерживается на низком уровне в течение примерно 6–9 мкс. Я подозреваю, что на этом этапе инженеры Broadcom следуют другим путем, который пытается снизить вероятность задержки полуфазы в линии с высокой емкостью. К сожалению, как мы видели, этого не происходит.

Следовательно, мой текущий код должен растягивать SCL за пределы ½ цикла в фазе чтения-postACK, что может занять некоторое время (например, преобразование АЦП). Если я не смогу

Текущие тесты, которые я выполняю, используют PIC16F1619 в качестве ведомого устройства. Подчиненное устройство использует цикл для увеличения тактовой частоты в командах чтения и записи, как до, так и после АКТ. Длина этого цикла плюс служебные данные варьируются от 3 мкс (меньше времени, в течение которого RPi удерживает низкий уровень SCL) до 90 мкс с шагом 0,35 мкс. У меня есть программа Python на RPi, которая будет различать значения для двух регистров, затем прочитать их и подтвердить, что значения считывания верны. Используемые значения

Пикан,
Broadcom преуменьшает значение этого, заявляя, что эта проблема возникает только на самом первом отрезке времени. Я не думаю, что это так. Вы должны это проверить. Advamation, кажется, следует за заявлениями Broadcom.

@rewolff Что ж, может быть что-то в их интерпретации. Если под «первым тактовым растяжением» они подразумевают «первый раз на данном этапе, когда SCL растягивается более чем на один тактовый перевод», то их описание является точным: если вы растягиваете более чем на один тактовый цикл, то да: в целом фаз, если вы растянетесь на> 0,5 цикла, вы в хорошей форме. По крайней мере, в тех смутных экспериментах, которые я проводил до сих пор; более точные эксперименты еще впереди.

Я счастлив провести несколько более удачных экспериментов, чтобы продемонстрировать, когда I2C RPi может и не может обрабатывать интервалы времени, и получить репродукции, которые BCM может отправить инженерам.

К сожалению, для решения этой проблемы им потребуется очень значительная версия кремния; им не нужно тикать тактовую частоту делителя SCL, когда SCL удерживается на низком уровне (внутренним или внешним источником). Это, вероятно, потребует изменения уровня кремния, что дорого; большинство ЭКО имеют металлический уровень, что… ну, не дешево, но намного дешевле кремния.

Моя главная цель здесь - охарактеризовать типы рабов, которые будут и не будут работать с RPi, с некоторыми экспериментальными доказательствами.

Похоже, нам нужны более надежные данные, такие как сценарии воспроизведения, чтобы убедить Broadcom перепроектировать контроллер I2C. Даже имея надежные данные, инженерам придется убедить руководство в том, что стоит пересмотреть кремний для следующей версии.

Тем не менее, я потрачу некоторое время на разработку воспроизводимых сценариев, чтобы инженеры BCM могли четко увидеть и протестировать проблему. Тем не менее, я буду полагаться на членов сообщества, которые сообщат мои выводы Broadcom; У меня нет на них канала.

Я должен кое-что прояснить по поводу моего предыдущего комментария для сообщества об изменениях кремния и металла.

Вы знаете, как, если вы получаете плату от SparkFun или Adafruit, на ней часто есть следы, которые вы можете вырезать или спаять, чтобы изменить ее поведение? На большинстве плат I2C есть дорожки, которые можно изменить, чтобы изменить адрес, включить или отключить подтягивающие резисторы и т. Д.

Разработчики микрочипов поступают так же. Они могут вносить множество изменений в металлические слои микрочипа, поэтому им не нужно менять слои кремния. Это связано с тем, что изменение кремниевых слоев сложно и дорого (например, замена микросхемы на плате), в то время как металлические слои изменить намного проще (например, изменение дорожек на плате).

В металлические слои можно внести много полезных изменений, потому что дизайнеры думают заранее и создают металлические соединения (по сути, перемычки), которые изменяют поведение микросхемы.

Но если есть изменение, которое они не планировали, и не могут понять, как это сделать, перенаправив трассировки внутри чипа, то им придется заменить кремний. Кремнию нужно гораздо больше планирования, проверки и маскировки, поэтому его сложно изменить.

Многие компании, если у них есть «достаточно хороший» кремниевый слой, будут использовать его как можно дольше. Они будут повторно использовать некоторые части кремниевого слоя в нескольких версиях чипа.

Я подозреваю, что здесь кроется BCM: им нужны веские доказательства того, что эту ошибку нельзя исправить в драйверах или металле, прежде чем они смогут оправдать реинжиниринг этой части кремниевого слоя с нуля.

Крайне маловероятно, что существующий кремний будет обновлен только для решения этой проблемы (есть лишний миллион долларов?). Впрочем, у будущих чипов может быть исправление, кто знает.

В среду, 5 сентября 2018 г., в 02:13:19 -0700 Джоэл Рэй Холвек написал:

Похоже, нам нужны более надежные данные, такие как сценарии воспроизведения, чтобы
убедить Broadcom перепроектировать контроллер I2C. Даже с
достоверные данные, инженерам придется убедить руководство, что
стоит пересмотреть кремний для следующей ревизии.

У них уже было шесть лет и три кремниевых доработки, в которых они
продемонстрировали свое решение: «исправлять не буду».

если вы растянетесь на> 0,5 цикла, вы в хорошей форме.

Я так не думаю. Каждый раз, когда вы отпускаете CLK в "непосредственно перед
Broadcom снова смотрит "период времени, вы получаете короткие импульсы. Я легко могу
задержать выпуск тактового сигнала, скажем, на 5 бесполезных микросекунд до
всегда быть вне 0,5 цикла. Но это не сработало.

В среду, 5 сентября 2018 г., в 02:28:53 -0700 Джеймс Хьюз написал:

Крайне маловероятно, что будет повторение
существующий кремний, чтобы исправить эту проблему (есть запасной 1 миллион долларов?). Будущее
чипы вполне могут иметь исправление.

Я в этом сомневаюсь. Мы перешли от BCM2835 с ИЗВЕСТНОЙ ошибкой к BCM2836 с
та же ошибка в BCM2837 с той же ошибкой в ​​BCM2837B0.

Как вы думаете, почему следующая версия будет другой?

У BCM есть целевой рынок: телефоны и ТВ-стики для этих чипов. В
их целевой рынок никто не делает программное обеспечение-I2C общего назначения
микроконтроллеры, такие как AVR и PIC. они НЕ собираются это исправлять.

Жалко, что это следствие требуется, хотя оно и велико. Когда я раньше спрашивал об опечатке, которая прикрывает это, я думал, что ее нет. Теперь это изменилось и есть URL-адрес? В идеале Broadcom помог бы сообществу, точно описав неисправность, и когда она произойдет, чтобы было легче с уверенностью найти обходные пути или оценку совместимых компонентов. Даже в пределах фрагмента соответствующего HDL, если они не хотят пытаться точно перевести это в описание.

Предложение остановить полубитовый делитель тактовой частоты при разрешении растяжения тактовой частоты является хорошим. Это сработает.

Проблема в том, что тогда часть модуля I2C должна будет работать на «полной тактовой частоте». Модуль I2C - это хороший маломощный модуль, потому что он обычно работает не быстрее 200 кГц.

Основной причиной моего поста было то, что я сказал в начале своего исходного поста :

Сейчас я играю с этой проблемой на RPi 3 Model B +, и я вижу результаты, отличные от описанных в статье Advamation. Кремний недавно не обновляли, не так ли?

Если у нас были существенные изменения в оборудовании или драйвере I2C после описания Advamation в

Я знаю, что основная проблема заключается в оборудовании, но насколько мне известно, кто-то мог экспериментально обнаружить, что изменение, казалось бы, несвязанного регистра в драйвере фактически меняет поведение этой ошибки. Я также не подтвердил, что BCM2837 имеет тот же модуль I2C, что и RPi 2 (последнее время, когда я смог найти окончательное подтверждение того, что оборудование I2C не изменилось с момента первого сообщения об этой проблеме). Я также не нашел никакой информации о степпингах BCM283x; насколько я знаю, в эпоху BCM2836 могло произойти изменение металла.

Меня не интересует критика Broadcom, размышления о том, как они могут изменить будущие версии, или что-то в этом роде.

Моя основная цель здесь - четко задокументировать текущее поведение; похоже, что со временем все изменилось. У меня есть второстепенная цель - позволить будущим пользователям воспроизвести мои эксперименты, чтобы увидеть, верны ли результаты, или внести улучшения или протестировать другие условия. У меня есть еще одна второстепенная цель - позволить инженерам Broadcom легко воспроизводить тесты, если они этого хотят. Оба эти фактора означают, что мне нужно публиковать свои эксперименты, что также помогает: из-за моего собственного высокомерия , если я публикую свои эксперименты, я буду больше стремиться сделать их более строгими.

Мой текущий экспериментальный план - использовать PIC16F1619 в качестве ведомой реализации; он достаточно быстрый и универсальный, чтобы проводить эксперименты с растяжкой часов, достаточно прост в работе и достаточно распространен, чтобы другие экспериментаторы могли воспроизвести мои результаты. Если результаты неоднозначны, я мог бы также провести эксперимент с FPGA. Я мог бы посмотреть, смогу ли я получить разумную детализацию, используя другой Raspberry Pi в конфигурации с битовым битом в качестве ведомого устройства, но я подозреваю, что мне понадобится что-то без всей ОС для тестирования в реальном времени.

Чтобы решить еще пару вопросов, которые возникли:

Извините, что мой исходный пост был неполным; Я случайно опубликовал ранний черновик. Я оставлю все как есть, поскольку внесенные мной изменения довольно незначительны.

Я не претендую на оригинальность идеи остановки делителя тактовой частоты, в то время как SCL внешне удерживался низким. Я читал это где-то в другом месте, но не помню где; Я думал, что это было от Герта ван Лоо в потоке растягивания часов I2C на raspberrypi.org , но я не могу найти его сейчас, поэтому я, должно быть, видел это в другом месте. Я не уверен, что это существенно изменит профиль мощности,

HW-блок I2C не был исправлен / изменен и вряд ли будет установлен в bcm2835 / 6/7, так как это потребует повторной установки чипа, что просто слишком дорого.

Я не знаю, кто такие Advamation, но они нереализованы для группы RPF (T), поэтому я не могу гарантировать точность статей.

Уважаемые, у меня на Pi 2B и 3 случился очень странный феномен, я пытаюсь объяснить:
Когда я начал внедрять BNO055 в конце июня, я использовал более старый Raspbian (сейчас у меня нет версии), и я получил много недопустимых адресов I2C с помощью i2cdetect. Для этого я поискал в сети и нашел этот форум с хорошей информацией. Для этого я изменил частоту I2C, как описано выше, и все призраки исчезают, и я могу работать. В середине августа я обновил Raspbian до raspbi-dev 4.14.62-v7 +, и система стала немного нестабильной, но я могу работать. От апдейта к апдейту система стала более нестабильной, заметил утечки на sd карте. Поэтому я переустановил Raspbian через NOOBS (Linux raspbi-dev 4.14.62-v7 + # 1134 SMP Tue 14 августа 17:10:10 BST 2018 armv7l) и забыл установить частоту I2C, но призраков не появилось. Хорошо, я не использую микроконтроллер на шине, только расширитель MEMS и GPIO, но я чувствую, что в коде Raspbian i2c есть обходной путь. Кроме того, я думаю, что обнаруженные утечки произошли из-за несовершенного обновления, я использую ту же карту, и утечек не обнаружено.

@ hmf2015 Эта проблема

Обычно призраки I2C не из-за этой проблемы. Чаще всего они возникают из-за:

  • У вас нет хорошего источника питания. Мне это нравится.
  • Ваши кабели слишком длинные. I2C плохо работает с кабелями длиной более 1 м.
  • Ваши кабели имеют емкостную связь. Если у вас скручены контакты I2C (SCL и SDA), это может создать проблему. Иногда люди используют кабели с витой парой (например, кабели Ethernet), которые скручивают контакты I2C, и это создает проблемы. Если вам нужно использовать кабели с витой парой, скрутите SCL с Vss (земля) и SDA с Vdd (3,3 В). Посмотрите на спецификацию I2C в разделе 7.5.
  • Ваше устройство I2C имеет 5 В. Raspberry Pi выполняет ввод-вывод при напряжении 3,3 В. Если напряжения разные, это может создать проблемы. (BNO055 требует 3,3 В, поэтому, если вы используете его с 5 В, у вас возникнут проблемы.)

Я сказал, что мы говорим об особой проблеме. Некоторые устройства могут создавать призраков из-за этой проблемы, но не многие устройства. Если устройства создают призраков из-за этой проблемы, они не создают много призраков. Я думаю, ваша проблема в другом.

Не понимаю, что вы имеете в виду, когда говорите, что "отметили утечки на sd-карте". Это важная проблема, но это не та проблема, о которой мы говорим в выпуске этой веб-страницы. Этот разговор о конкретной ошибке. Эта ошибка не влияет на SD-карты.

Я не думаю, что недавний Raspbian изменил принцип работы I2C. Мы думаем, что Raspbian не может исправить эту ошибку. Мы можем ошибаться. Спасибо, что рассказали нам об этом.

Если вы сообщаете нам эту информацию только для того, чтобы помочь нам, мы благодарим вас. Если вы сообщаете нам эту информацию, чтобы попросить о помощи, вы можете спросить на форумах Raspberry Pi . На форумах обсуждают многие вещи, такие как I2C, SD-карты, расширители GPIO и многое другое. То, что вы видите, может быть тем же, о чем мы говорим, но это могут быть разные вещи. Люди на форумах могут помочь вам узнать, какие проблемы вы наблюдаете.

Спасибо, что сообщили нам эту информацию!

Спасибо за ответ, но проблема с SD-картой возникла из-за O / S, я проверил карту на моем (Unix) хосте, и все в порядке, и теперь тот же самый CAD работает идеально после новой установки.
Призраки на шине I2C исчезают с большей частотой, и теперь после переустановки они не появляются, проблемы с R / C и отражения я, думаю, могу исключить. Я знаю проблемы с напряжением 3,3 В, но минимальный уровень на 1 меньше.
В корпусе BNO055 есть регулятор напряжения.
Я также думал, что проблемы с I2C будут такими же, как и раньше, но это не так, на данный момент у меня нет времени (и интереса) заглядывать в исходный код Raspbian, чтобы обнаружить различия, мне интересно по рабочей среде.
Список элементов должен показывать только то, что я работаю в среде Andoid (с настоящим Unix), поскольку BCM поддерживает, а не с микроконтроллером, который я подключаю через последовательную линию или USB, так как я ленив. В вашем окружении условия более жесткие, чем у меня, поэтому я не могу сказать, уменьшились ли ваши проблемы, но я надеюсь.

Привет hmf2015,
Это не форум. Это баг-трекер. В этом списке комментариев обсуждается ошибка, не имеющая отношения к вашим проблемам. Пожалуйста, обсудите вашу проблему на соответствующем форуме или в службе поддержки. Опять же, мы ценим ваш вопрос: «Может быть, это то же самое? Может быть, мое описание поможет решить эту ошибку?» но теперь мы точно знаем, что то, что вы видите, не имеет отношения, пожалуйста, не «загрязняйте» это обсуждение дальше.

@popcornmix
привет, давным-давно вы упомянули о проблеме с конечным автоматом I2C во время перезапуска и опубликовали код по этой проблеме.
Я не уверен, что вы имели в виду, но у меня проблема с кодеком WM8731, подключенным к I2C.
После 2-3 перезапусков шина I2C полностью зависает. i2cdetect не показывает никакой информации, кроме 1-й строки, и тоже вешает трубку. Единственный способ восстановления - это цикл выключения / включения.
Похоже ли это на проблемы, о которых вы упомянули?
Я использую основное ядро ​​4.19.

@ sergey-suloev Когда i2cdetect не продолжает сканирование после 8 или 16 адресов, я бы сказал, что это не связано с этой проблемой. Проблема возникает, когда устройства растягивают тактовую частоту, чтобы указать, что они еще не готовы к следующему тактовому циклу. Когда I2C был разработан почти 40 лет назад, это можно было представить и для аппаратных реализаций. Но в настоящее время оборудование всегда готово вовремя для обработки следующего тактового цикла, потому что 10 микросекунд - это возраст для чего-то, реализованного на оборудовании.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги