Linux: I2C Broadcom علة الحل البديل.

تم إنشاؤها على ٢٠ مارس ٢٠١٣  ·  73تعليقات  ·  مصدر: raspberrypi/linux

يحتوي Broadcom BCM2835 على خطأ (في الجهاز) في وحدة I2C.

يطبق BCM "تمديد الساعة" بطريقة سيئة:

بدلاً من ضمان حد أدنى من "hightime" للساعة ، تتيح BCM تشغيل ساعة I2C داخليًا ، وعندما يحين وقت قلب الساعة مرة أخرى ، فإنها تتحقق من ارتفاع أو عدم ارتفاع الساعة ، وإذا كانت منخفضة ، يفعل "امتداد الساعة". ومع ذلك ، إذا تم إصدار إشارة الساعة التي تشير إلى أنها جاهزة لساعة جديدة في غضون بضع نانو ثانية قبل هذا الفحص ، فقد يصبح نبض الساعة قصيرًا مثل 40 نانو ثانية. (هذا هو أدنى مستوى يمكنني قياسه ، وهذا بالطبع نادر جدًا). مع ساعة I2C 100 كيلو هرتز (10 ميكرو ثانية) ، تكون اللحظات "السيئة" لتحرير الساعة على بعد 5 ميكروثانية.

يتطلب عبدي نبض ساعة لا يقل عن 500 نانوثانية. (والذي يجب أن يكون عامل أقصر بعشر مرات مما يجب أن يولده السيد عند تكوينه لتشغيل 100 كيلو هرتز).

هذا خطأ في الأجهزة لا يمكننا فعل الكثير بشأنه في الوقت الحالي. (نصيحة لشباب الأجهزة: بدلاً من تنفيذ تمدد الساعة بهذه الطريقة: منع عد عداد CLOCKDIV بينما تظل الساعة منخفضة. من المحتمل أن يمتد هذا على مدار الساعة بضع ساعات سريعة في كل دورة ، لكن مطابقة المعايير ستتحسن بشكل كبير ).

عندما يحدث هذا ، سيرسل BCM بايتًا ، مع نبضة ساعة أولية قصيرة جدًا. لا يرى العبد نبضة الساعة الأولى ، لذا عندما يحين وقت ACK في نهاية البايت ، لا يزال العبد ينتظر البتة الثامنة. تفسر BCM هذا على أنه "NAK" وتجهض نقل I2C. ولكن في تلك المرحلة الزمنية ، يرى العبد نبض الساعة الثامن ويصدر "ACK" (يسحب خط SDA منخفضًا). وهذا بدوره يعني أن BCM لا يمكنها إصدار شرط "START" مناسب لعملية التحويل التالية.

الحل البديل المقترح للبرامج لتقليل تأثير هذا الخطأ في الأجهزة: عندما يتم إحباط النقل بسبب "NAK" للبايت ، قم بإصدار دورة ساعة إضافية واحدة قبل STOP لمزامنة العبد. ربما يجب القيام بذلك في البرنامج.

يحدث هذا فقط في "مسار الخطأ" عندما لا يعطي العبد بايتًا. ربما يكون من الأفضل القيام بذلك فقط عندما لا يكون البايت الأول في عملية النقل ، حيث لا يمكن أن يحدث الخطأ في البايت الأول من النقل.

هل ينتمي إصلاح البرنامج هذا إلى السائق؟ نعم. إنه برنامج تشغيل لقطعة من الأجهزة بها خلل. من واجب السائق جعل هذا الجهاز يعمل بأفضل شكل ممكن.

Bug

التعليق الأكثر فائدة

مرحبًا 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 عند إعادة التشغيل

بالنسبة لـ 1 ، يرى جيرت أنه لا يوجد حل بديل مضمون.
إذا كان الرقيق I2C لا يدعم تمديد الساعة فأنت بخير.
إذا امتدت ساعة I2C بمقدار محدد ، فإن خفض تردد ساعة I2C يمكن أن يتجنب المشكلة
يعد التبديل إلى سائق ضجيج قليلاً للعبيد الذي لا يقع في الحالات السابقة حلاً آمنًا.

لا أعرف ما إذا كان اقتراحك سيعمل. سأكون مهتمًا بمعرفة ما إذا كان يقلل من المشكلة ، أو يصلحها تمامًا.

يقول غيرت أن لديه وصفًا للخطأ الذي سيحاول إطلاق سراحه.

بالنسبة إلى 2 ، في برنامج تشغيل GPU 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 ، ثم تسوء الأمور. لذلك ، في هذه الحالة ، قد يحدث خطأ واحد من كل 20 عملية تحويل. (تشير المواصفات إلى 250 نانوثانية على الأقل لنبض الساعة. هذا في الواقع لا يعني أنه لن يتم رؤيته إذا كان أقصر. أعتقد أن فرص رؤيته تتراوح خطيًا من 100٪ عند> 250 ثانية إلى 0٪ عند 125ns.)

لقد قضيت الأمس في تمديد فترة تمديد الساعة بطريقة تجعلها تقترب من علامة 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 ميكرو ثانية على مدار الساعة) ، فربما تعمل الساعة على العبد أسرع بنسبة قليلة وتسبب الخطأ في تشغيل نصف دورة في وقت سابق. لذا فإن كلا طرفي دورة نصف الساعة خطير ، ولا بد لي من أن أهدف إلى دورة ساعة قصيرة ولكنها صالحة بدرجة كافية.

التغيير في الوحدة هو IMHO بسيط: عندما يكون SCL "مدفوعًا عاليًا" (أي لا يتم دفعه على الإطلاق) ، أوقف الساعة الرئيسية لوحدة I2C. هذا له تأثير جانبي للسماح بحافلات I2C أطول بكثير لأن التمدد التلقائي للساعة يحدث عندما تكون سعة الحافلة أعلى من المواصفات.

شكرًا لمحاولة المساعدة ، iz8mbw ، لكن هؤلاء لا علاقة لهم بهذا الخطأ (في الأجهزة).

لقد قمت بقياس ساعة I2C الخاصة بي وظهرت على أنها 100 كيلو هرتز والتي يعتقد السائق أنها يجب أن تكون كذلك. لدى السائق كائن "مصدر ساعة" يستفسر عن التردد ويستخدمه. لم أقم بعد بتجهيز السائق الخاص بي لطباعة التردد.

فقط للحصول على معلومات للأشخاص الذين يرغبون في رؤية الخطأ أثناء العمل ، لدي بعض "الدليل" في شكل تفريغ محلل منطقي.
حسنًا ، يمكنني إرفاق الصور ، لكن ليس ملف تفريغ LA الثنائي. هذا واحد هنا: 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 ميكروثانية.

يتم الآن اختبار التأخيرات المختبرة لـ ACK مع التابع attiny:
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 قد اكتملت. أفترض أنني بحاجة إلى تعلم تجميع وحدات kernel وتشغيل الاختبارات الحالية مقابل الكود أعلاه.

ألا يمكننا فقط إجبار النواة على تجاهل أجهزة I2C واستخدام I2C المستند إلى bitbanged GPIO على نفس المسامير؟ أعتقد أن النفقات العامة لذلك ستكون مقبولة أكثر من الأخطاء الموجودة في الجهاز نفسه.

ما النفقات العامة التي تتوقعها؟ يتم تعيين برنامج التشغيل الحالي افتراضيًا على ساعة 100 كيلو هرتز. لذا فإن قراءة 10 بايت من مستشعر i2c البيني تستغرق حوالي 1 مللي ثانية. إذا كنت تستخدم bitbang ، فمن المحتمل أن تقوم بتشغيل دورات وحدة المعالجة المركزية طوال هذا الوقت ...

أفضّل أن يقوم السائق اختياريًا بدعم bitbanging i2c من خلال معلمة وحدة (أو ربما وحدة منفصلة إذا كان ذلك أكثر ملاءمة).

لا تستخدم العديد من الأجهزة تمدد الساعة (أو تمدد الساعة بمقدار محدد لذلك يمكن أن تعمل بشكل صحيح بسرعة منخفضة) ، لذلك لا يزال برنامج تشغيل الأجهزة I2C مفضلًا في تلك الحالات.

يحتوي kernel نفسه على برنامج تشغيل لـ bitbanged I2C على دبابيس GPIO ، هذا المحرك لديه حمل أقل بكثير من bitbanging من مساحة المستخدمين ، ويكشف نفس API مثل برامج تشغيل الأجهزة I2C. اقتراحي هو تجميع كل من برنامج التشغيل هذا وبرنامج تشغيل الأجهزة I2C كوحدات نمطية ، ثم تحميل برنامج تشغيل الجهاز افتراضيًا.

تضمين التغريدة
هل تستخدم برنامج تشغيل bitbanged I2C على Pi؟
ما هي خيارات التكوين التي أضفتها لإنشائها؟ أي مصدر بقع؟
ماذا تفعل لاختيار برنامج التشغيل المراد استخدامه (modprobe؟ different / dev / devices؟)

لم تستخدم برنامج التشغيل على Pi ، لكن لدي صديق يستخدمه بنجاح على لوحة BeagleBoard.
خيار التكوين هو I2C_GPIO.
إذا تم تكوين كل من ذلك وبرنامج تشغيل broadcom كوحدات نمطية ، فسيكون اختيار برنامج التشغيل بسيطًا مثل تحميل وحدة kernel.
لا تحتاج وحدة GPIO إلى معلمات لإخبارها بأي كائنات GPI يجب استخدامها مثل SDA و SCL ، لا أعرف ما هي المعلمات ، ولكن بناءً على المصدر غير الموثق جيدًا في dirvers / i2c / busses / i2c-gpio.c ، يبدو أن المعلمات المناسبة هي 'sda = X scl = Y' حيث X و Y هما الدبابيس التي تستخدمها النملة.

لا توفر الوحدة النمطية i2c-gpio نفسها أي طريقة لتمرير المعلمات إليها. لذا فأنت بحاجة إلى وحدة أخرى تسجل بيانات النظام الأساسي وتكوِّن على الأقل رقم الناقل ودبابيس SDA و SCL. لقد كتبت إثباتًا لمفهوم هذه الوحدة النمطية وعملت حتى على الدبابيس 0 و 1 ولكن بدون تحميل i2c-bcm2708 (تم اكتشاف pcf8574 بواسطة i2cdetect ، تمكنت من تشغيل بعض مصابيح LED باستخدام وحدة gpio-pcf857x). ولكن بعد ذلك قمت بنسخ جهاز الكمبيوتر الخاص بي عند تغيير المسامير (وليس لدي أي رقائق i2c أخرى في الوقت الحالي) لذلك لم أتمكن من اختبارها حقًا. ها هو الرمز

تضمين التغريدة
قد يكون من المفيد إجراء معاملات وحدة sda_pin / scl_pin. كما طلب سحب.
يمكن لأي شخص أن يؤكد أن هذا يعمل لهم؟

هذا أقل أهمية مما يبدو: إنه يتوقع أن يتم تمرير بنية بيانات النظام الأساسي على طول الطريق.

من ناحية أخرى ، لا تملي المنصة أي GPIOs التي ستستخدمها اليوم ، لذا فإن العمل على تغييرها يبدو معقولاً. (عادةً ما تحدد بيانات النظام الأساسي: "كيف يتم توصيل / هذا / الكمبيوتر".)

تضمين التغريدة
أخطط لجعلها قابلة للتكوين ، لم يكن لدي ما يكفي من الوقت أمس. أود أيضًا أن يكون قادرًا على إنشاء أكثر من حافلة في وقت واحد. ربما بطريقة ديناميكية ، مثل ملفات GPIOS export و unexport sysfs (لكنني لست متأكدًا مما إذا كان من الممكن إلغاء تصدير مثل هذه الحافلة)؟ أوه ، ووجدت جهاز كمبيوتر آخر PCf8574 ويمكنني أن أؤكد أنه يعمل جيدًا أيضًا على دبابيس GPIO مختلفة عند استخدام مقاومات سحب خارجية. للأسف ، ليس لدي أجهزة I²C أكثر تطورًا لاختبارها. فهل أنت مهتم بتوفير هذه الوحدة في شجرة النواة الافتراضية؟

تضمين التغريدة
ليس لدي إعداد لاختبار وحدات مثل هذه. ومع ذلك ، فإن أي ميزات للأجهزة توفرها الشريحة (مثل I2C) يجب أن تحتوي على برامج تشغيل kernel للسماح لمزيد من الأشخاص باستخدامها. إذا كان جهاز I2C يحتوي على أخطاء من شأنها أن تمنع الأشخاص من استخدام أجهزة طرفية معينة ، فإن الأصوات البديلة تستحق العناء.

لذلك ، إذا قمت بإنتاج برنامج تشغيل جديد يبدو غير ضار للأشخاص الذين لا يستخدمونه (على سبيل المثال ، تم إنشاؤه كوحدة نمطية ، ولا يتم تحميله شيئًا حتى يتم تحميله) ، وهناك بعض الأدلة (مثل بعض تأكيد تقارير المستخدم) أنه يعمل بشكل صحيح ، فأنا أنا سعيد لقبول العلاقات العامة.

هل تم إصلاح المخلفات الخطرة على BCM2837 (في RPi 3)؟

تخميني هو: لا. لكن ربما ليس لدي الوقت لاختبار هذا اليوم.

BCM2837 I2C لم يتغير.

هذا مؤسف ، لكن شكرا على المعلومات.

هذا مزعج جدا.

أنا موافق. هل لدى أي شخص رابط BCM2837 errata ، أو ما شابه ، يشير إلى أن المشكلة لا تزال قائمة؟ سيكون مفيدًا عندما يتعين علينا نقل الأخبار. أو @ P33M ، ربما يمكن الاقتباس منك

إنه موثوق ، على الرغم من أنه لا يعمل مع Broadcom.

هذا طيب. لكنني بحثت بالفعل في Google ، وبصرف النظر عن P33M كونها M33P في مكان آخر ، أجد صعوبة في العثور على معرف يمكنني تمريره بشكل مفيد. هذا جيد ، لكن يعني أنه ليس مصدرًا رائعًا للاقتباس. :-) لذا سيكون ارتباط الخطأ مفيدًا.

@ P33M يعمل مع Raspberry Pi. يمكنك التعامل مع ما يقوله على أنه موثوق.

لا أعتقد أن هناك قائمة أخطاء ، ربما ينبغي أن تكون كذلك. لقد تركته
لتأكيد هويته أم لا!

في 15 مارس 2016 الساعة 14:30 ، كتب RalphCorderoy [email protected] :

هذا طيب. لكنني بحثت بالفعل في Google ، وبصرف النظر عن P33M كونها M33P
في مكان آخر ، أجد صعوبة في العثور على بطاقة هوية يمكنني نقلها بشكل مفيد. وهو ما يرام،
لكنه يعني أنه ليس مصدرًا رائعًا للاقتباس. :-) لذلك سيكون ارتباط الأخطاء
سهل.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub:
https://github.com/raspberrypi/linux/issues/254#issuecomment -196845789

RalphCorderoy أنا موظف في Raspberry Pi (للتجارة) المحدودة ، إجابتي موثوقة.

@ P33M ، تا ، هذا

هذا يؤثر على مشروع أعمل عليه. لحسن الحظ ، لدي سيطرة كاملة على البرامج الثابتة للجهاز التابع وتمكنت من إضافة حل بديل لإضافة تأخير نصف فترة إضافي (امتداد الساعة) في ردودي التي تتخطى السلوك السيئ.

يمكن العثور على تحليل جيد للمشكلة على advamation.com .

هل هذه الأجهزة السيئة في تطبيق Broadcom's I2C أم أن هناك تعديلات على kernel ممكنة لجعل الأجهزة تعمل بشكل صحيح؟

لقد اشتركت للتو في هذه المشكلة لأنني واجهت هذا أيضًا مع منتج أقوم بتطويره
الذي يستخدم i2c بين AVR و Pi. الآن أنا بحاجة إلى إعادة التفكير في الأمر.
هل استخدم أي شخص أي شكل موثوق من ضجيجا بت i2c؟

@ mwilliams03 ، قد تكون مهتمًا بهذا المشروع ، حيث نجحت في إنشاء اتصال I2C بتردد 100 كيلو هرتز و 400 كيلو هرتز بين Raspberry Pi و AVR. أنا لست مضطربًا ، ولكن بدلاً من ذلك أستخدم دعم I2C للأجهزة وإدخال التأخيرات في النقاط الرئيسية. اتضح أن AVR بطيء بدرجة كافية بحيث لا تكون هناك حاجة إلى تأخير إضافي عند 400 كيلو هرتز.

على وجه الخصوص ، هنا معلومات حول قضايا I2C . لاحظ أيضًا أن وحدة TWI الخاصة بوحدة AVR بها مشكلة تمنع القراءة السريعة .

شكرًا @ pdg137 ، لقد جربته وفي المرة الأولى حصلت على 1.2 مليون قراءة بدون أخطاء وما زلت أواصل.

rewolff يبدو أنه تم حل هذه المشكلة. إذا كان هذا هو الحال ، الرجاء إغلاق هذه المشكلة.

والان .... اضف مستوي شيفتر وكابل تمديد 40 سم .. هل يعمل اذن؟ من المحتمل أن يتسبب هذا في تأخير كافٍ على الجانب "العلوي" من أشكال الموجة ، وفجأة ، يعود الخطأ مرة أخرى.

بقدر ما أستطيع أن أقول ، لا يزال برودكوم والموظفين يعتقدون أن هذا الخطأ يقتصر على أول 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

بقدر ما أستطيع أن أقول ، لا يزال برودكوم والموظفين يعتقدون أن هذا الخطأ يقتصر على أول 5 ميكروثانية (في الواقع نصف ساعة) بعد الجزء الأخير من البايت.

rewolff : أود أن أتفق مع موظفي Broadcom. في اختباراتي ، باستخدام Raspberry Pi 3 و 100 كيلو هرتز I2C (الذي يتباطأ إلى 62 كيلو هرتز عند اختناق وحدة المعالجة المركزية) ، أحصل على نتائج مشابهة

تبدو الرسوم المتحركة سليمة. ومع ذلك فهو لا يتماشى مع تجربتي. ربما يجب أن أقوم بإعداد اختبار. قد يستغرق بعض الوقت. إنه مشغول بأشياء أخرى.

ولكن إذا كان الأمر كذلك ، فإن مجرد "النوم (10)" في روتين المقاطعة الخاص بي (مع تمديد ساعة الأجهزة) سيفي بالغرض ويجعل الأشياء غير مغلقة. أنا متأكد من أن الأمر لم يكن كذلك. :-(

rewolff : في Raspberry Pi 3 ، رأيت أن وحدة المعالجة المركزية يتم خنقها إلى 600 ميجاهرتز ، مما أدى إلى سرعة I2C الافتراضية 62 كيلو هرتز. لذلك يجب أن تنام لمدة 17 ميكروثانية في ISR الخاص بالعبد إذا بدأ ISR على حافة هبوط SCL أو إذا كنت تعتقد أن وحدة المعالجة المركزية قد تنخفض إلى أقل من 600 ميجاهرتز ، فاستمر في النوم لفترة أطول.

هل سيكون من الممكن تضمين وحدة i2c-gpio-param الخاصة بـkadamski في نواة Raspberry Pi؟ أستطيع أن أؤكد أن هذا النهج يبدو أنه يعمل بشكل جيد مع تطبيقي (برنامج AVR I2C التابع) وأنه من المرهق إلى حد ما تثبيت الرؤوس المطلوبة لنواة التوت ، لذا فإن توفرها سيكون أمرًا رائعًا.

سيكون أيضًا حلاً جيدًا لمعالجة خطأ HW الكامن وراء هذه المشكلة برمتها.

onnokort تقصد مثل i2c-gpio overlay الموجود في النواة الحالية منذ نوفمبر 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 من قراءتي خيار لائق.

الحل البديل الموصى به للأجهزة التي بالتأكيد لا تعمل بشكل جيد مع أجهزة I2C الخاصة بنا هو استخدام i2c-gpio overlay ، وهو عبارة عن دبابيس bitbashes.

خلاف ذلك ، يتم دعم امتداد الساعة في مرحلة 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 يبدو أن هرتز سريع جدًا بالنسبة إلى BNO055 ، فهو يعمل ولكن القيم خاطئة أحيانًا. أعترف ، لم أختبر التردد بواسطة مرسمة الذبذبات ، لقد قرأت فقط الملف / sys / class / i2c-adaptor / i2c-1 / of_node / clock-frequency ، لذلك ترك بعض عدم اليقين مفتوحًا. الآن بدأت في تنفيذ واجهة كاملة لـ BNO055 في ADA.
الوجه: يظهر خطأ الأجهزة في معالجة BMC I2C فقط عند 100_000 هرتز ، ويجب تأكيده.

فقط لمعلوماتك ، يحدث خطأ الأجهزة عندما يقوم الجهاز التابع بتمديد الساعة ويطلق خط SCL بعد فترات ساعة من 0.9 إلى 0.999 I2C. سيبدأ الخط في الارتفاع ، وستقول أجهزة pi: أوه ، لم يقم بتمديد الساعة ، لذا يمكنني توفير نبض الساعة التالي عن طريق سحب خط الساعة منخفضًا مرة أخرى.

يحدث الخطأ عندما يكون الوقت المتبقي في فترة الساعة كافيًا لخط clk لتجاوز الحد "HIGH" للتوت ولكن ليس للأجهزة التابعة أو عندما يكون لدى التابع تصفية ضوضاء ويعتبر مرتفعًا خلال <x٪ من دورة ساعة I2C العادية خلل.

لا يحدث هذا "عند 100 كيلو هرتز فقط" ، ولكن أيضًا على العديد من الترددات الأخرى ، باستثناء أن وقت استجابة الجهاز التابع يجب أن يكون بقيمة مختلفة.

لنفترض أن الساعة 100 كيلو هرتز ، لذلك ستكون الدورة العادية 5us عالية و 5us منخفضة. افترض الآن عند t = 0 أن pi بدأ آخر دورة على مدار الساعة بسحب خط الساعة منخفضًا. عند t = 5us ، يطلق pi إشارة الساعة ، لكن العبد لا يزال مشغولًا ويبقي الساعة منخفضة. عند t = 9us يتم الرقيق ويطلق إشارة الساعة. عند t = 10us ، سينظر pi إلى إشارة الساعة ، ويفكر: حسنًا ، لا توجد ساعة ممتدة ، لذا تابع ، وسحب إشارة الساعة منخفضة مرة أخرى. كانت إشارة الساعة عالية الآن فقط لـ 1us (أقل قليلاً بسبب السعة وثابت وقت مقاومات السحب) وقد لا يراها العبد. الآن لا يصبح الجهاز المختلف جاهزًا بعد 9 ميكروثانية ، ولكن بعد 10.5. الآن عند 100 كيلو هرتز ، سوف يرى باي "لا يزال منخفضًا ، تمتد الساعة ، انتظر 5 ميكروثانية أخرى. الآن سنحصل على نبضة ساعة 4.5 ميكروثانية وستعمل الأشياء. لكن تشغيل هذا الجهاز عند 90 كيلو هرتز ، وسيواجه مشكلة. الآن ستنظر pi في 11 ميكروثانية من البداية ، وستكون إشارة الساعة عالية لأقل من ميكرو ثانية -> مشاكل.

الأشخاص الذين يشتكون من هذا ليسوا من لديهم تلك الأجهزة الأخرى. هؤلاء يعملون على 100 كيلو هرتز الافتراضي. لكن الخطأ لا يزال حقيقيًا وسيحدث على تلك الأجهزة ببساطة بسرعات ناقل أخرى غير الأجهزة التي نملكها أنا وأنت.

شكرًا لك على الرد ، إنه يشرح جيدًا ، لماذا حصلت على نقل موثوق به على الترددات التي اخترتها:
عند 100_000 هرتز ترتفع المشاكل في الفترة من 9 إلى 9.99 µsec
عند 85_000 هرتز ، تبدأ المشكلات من 1_000_000 / 85_000 * .9 = 1059 µsec> 9.99 ثانية ، لذلك يتم تجاهل امتداد الساعة ، أفترض ، بالنسبة لجميع الترددات الأقل من 85_000 هرتز ، تكون نقطة بداية المشكلات أعلى من 1059 ميكرو ثانية .
عند 115_000 هرتز ، تكون دورة الحافلة هي 1_000_000 / 125_000 = 8.7 µsec <9 sec ، وبالتالي يتم اكتشاف امتداد الساعة بشكل صحيح ، لجميع الترددات الأعلى من 115_000 هرتز ، تكون دورة الحافلة أقل من 8.7 sec.
لذلك عندما أواجه مشاكل يمكنني حساب التكرار الذي أحتاجه.
(قرأت المعلومات على http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html ،
هناك لوحظ .5 بدلاً من .9 من فترة).

حسنا. يعتمد ذلك على ما يكتشفه عبدك كإشارة ساعة صالحة. ومقدار التأخير الذي يحدثه RC في حافلتك. في حالتي ، يعتبر AVR الذي أستخدمه كعبد أن النبضات التي تقل عن دورتين على مدار الساعة تمثل خللاً. مع ساعة RC داخلية تبلغ 8 ميجاهرتز (+/- 10٪ !!!) ، يجب أن يكون النبض على الأقل 250 نانوثانية ليتم اكتشافه. تتطلب مواصفات I2C 5 ميكروثانية ، لذلك هناك عامل 20 "هامش" بين ما هو مطلوب رسميًا وما لم يعد يعمل.

في البداية اعتقدت أنني سأزيد من امتداد الساعة في عبدي ينتج قليلاً ليقول 12us. يعمل ذلك حتى تضيف سعة الحافلة تأخيرًا كافيًا لإحداث مشكلة مرة أخرى. لذلك من الصعب جدًا حل المشكلة. مزعج أن تضطر إلى إخبار عملائك بعدم استخدام معيار i2c بسرعة 100 كيلو هرتز.

عذرًا ، لكنني احتجت إلى بعض الوقت لكتابة سيناريو تنفيذ واختبار كامل.
أشكرك على كل المعلومات التي قدمتها لي ، لقد كانت مفيدة للغاية.
تم إنشاء سيناريو الاختبار الخاص بي باستخدام 2 MEMS (BNO055 معبأ كـ GY-055 ، MPU9255 معبأ كـ MPU-9250/6500 ، سجل WHO_AM_I يقول MPU9255) وموسع GPIO 1 PCF 8574 (معبأ PCF 8574).
تم ضبط ساعة I2C في Pi (2b) على 125 كيلو هرتز ، وتم التحقق من ذلك عن طريق قراءة / sys / class / i2c-adaptor / 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. لم يتم تسريع السيليكون مؤخرًا ، أليس كذلك؟

النسخة القصيرة هي ، يبدو أن الأمور تعمل إذا امتدت إلى القراءة المسبقة أو الكتابة المسبقة أو الكتابة postACK ؛ المرة الوحيدة التي أحتاج فيها للتأكد من التمدد لفترة طويلة أو لا على الإطلاق هي read-postACK. ما زلت بحاجة إلى تنظيف تجربتي قبل أن أتمكن من قول أي شيء مؤكد.

أولا ، ملاحظة حول المصطلحات. تقول مقالة Advamation:

لذلك ، يعمل I2C مع Raspberry Pi فقط إذا كان
العبد لا يستخدم إطالة الساعة على الإطلاق ، أو
يقوم التابع بتمديد الساعة فقط في النهاية / مباشرة بعد مرحلة I2C-read-ACK (بعد قراءة ACK / NACK) ، ولكن بعد ذلك بأكثر من 0.5 فترة ساعة.

يبدو مصطلح "I2C-read-ACK-phase" غامضًا إلى حد ما. إذا كان أمر قراءة I2C (على سبيل المثال ، تم تعيين بت R / W̅ للعنوان البريدي) ، فسيكتب العبد بت A̅C̅K̅ ، وليس قراءته ، على عكس الأصل. عندما أقول "read-postACK" هنا ، أعني أن بت R / W / تم تعيينه بعد العنوان مباشرةً (ويفترض أنه لم يتغير بواسطة بروتوكول مثل SMBus) ، لذلك كتب العبد للتو رد A̅C̅K̅.

كما تم التلميح هنا ، يبدو أنه إذا شعر RPi أن SCL يتم تثبيته منخفضًا بواسطة أحد الرقيق ، فسوف يؤخر ساعة SCL الداخلية بمقدار نصف دورة واحدة (5μS). يتم تشغيل الخطأ إذا كان التابع يحمل SCL منخفضًا لمدة نصف دورة واحدة تقريبًا. إذا حدث ذلك ، فسيظل RPi يترك SCL يرتفع ، ثم يسحبها لأسفل فورًا بعد تشغيل ساعة SCL. ينتج عن هذا نبض على مدار الساعة يعمل ، والذي قد تراه بعض الأجهزة كنبض بينما لا يراه الآخرون. (كمرجع: تشير مواصفات I2C إلى وقت مرتفع اسمي لـ SCL يبلغ 5μS ، وتحدد وقتًا لا يقل عن 4.0μS عند 100 كيلو هرتز ، وهي السرعة الافتراضية لواجهة RPi I2C.)

في تجاربي ، في مراحل القراءة المسبقة ، والكتابة المسبقة ، والكتابة اللاحقة ، سيضمن RPi أن أقصى وقت لـ SCL يسمح به هو 4μS أو نحو ذلك. بدت على استعداد لدفع ساعة SCL إلى الوراء في تلك المراحل. أظن أن RPi أخذ عينات من خط SCL بعد فترة وجيزة من إطلاقه ، وإذا كان SCL لا يزال منخفضًا ، فقد دفع ساعة SCL الخاصة به إلى نصف مرحلة.

ومع ذلك ، في مرحلة القراءة اللاحقة للحزمة ، رأيت أن RPi ستصدر ساعات تشغيل (<4μS ، غالبًا 2μS أو أقل) إذا كان خط SCL منخفضًا لمدة 6-9μS. أظن أنه في هذه المرحلة ، يتبع مهندسو Broadcom مسارًا مختلفًا يحاول تقليل احتمالية اضطرارهم لتأخير نصف الطور على خط عالي السعة. للأسف - كما رأينا - إنها تقصر.

لذلك ، يحتاج الكود الحالي الخاص بي إلى تمديد SCL إلى ما بعد دورة في مرحلة read-postACK للقراءات التي قد تستغرق بعض الوقت (مثل تحويلات ADC). إذا فشلت في ذلك

الاختبارات الحالية التي أجريها تستخدم PIC16F1619 كجهاز تابع. يستخدم الجهاز التابع حلقة لتمديد الساعة في كل من أوامر القراءة والكتابة ، قبل وبعد الحزم. يختلف طول هذه الحلقة بالإضافة إلى الحمل الزائد من 3μS (أقل من الوقت الذي يحمل فيه RPi SCL منخفضًا) إلى 90μS بزيادات 0.35μS. لدي برنامج Python على RPi والذي سيختلف القيم لسجلين ، ثم أعاد قراءتهما ، وأؤكد أن قيم إعادة القراءة صحيحة. القيم المستخدمة

بيكوان ،
لقد قللت شركة Broadcom من أهمية ذلك بإعلانها أن هذه المشكلة تحدث فقط في أول امتداد للساعة. لا أعتقد أن هذا هو الحال. يجب أن تكون قادرًا على التحقق من ذلك. يبدو أن Advamation يتبع تصريحات Broadcom.

rewolff حسنًا ، قد يكون هناك شيء في تفسيرهم. إذا كانت تعني ، من خلال "امتداد الساعة الأول" ، "المرة الأولى في مرحلة معينة التي يتم فيها تمديد SCL بأكثر من ترجمة ساعة واحدة" ، فإن وصفها يكون دقيقًا: إذا قمت بالتمديد بأكثر من دورة ساعة واحدة ، إذن نعم: في الكل إذا قمت بالتمدد بمقدار> .5 دورة ، فأنت في حالة جيدة. على الأقل ، في التجارب الغامضة التي أجريتها حتى الآن ؛ تجارب أكثر دقة لم تأت بعد.

يسعدني إجراء بعض التجارب الأفضل لإثبات متى يمكن لـ RPi I2C التعامل مع تمددات الساعة ولا يمكنه ذلك ، والحصول على نسخ يمكن أن ترسلها BCM إلى المهندسين.

للأسف ، هناك معدل كبير جدًا من السيليكون يحتاجون إليه لإصلاح هذه المشكلة ؛ لا يحتاجون إلى تحديد ساعة مقسم SCL عندما يكون SCL منخفضًا (بواسطة مصدر داخلي أو خارجي). ربما يتطلب ذلك تغييرًا على مستوى السيليكون ، وهو أمر مكلف ؛ معظم الاقتصاديات ذات المستوى المعدني ... حسنًا ، ليست رخيصة ، لكنها أرخص بكثير من السيليكون.

هدفي الرئيسي هنا هو وصف أنواع العبيد التي ستعمل ولن تعمل مع RPi ، مع بعض الأدلة التجريبية.

يبدو أننا بحاجة إلى بيانات أكثر صلابة ، مثل سيناريوهات إعادة المحاولة ، لإقناع Broadcom بإعادة هندسة وحدة التحكم I2C. حتى مع وجود بيانات قوية ، سيتعين على المهندسين إقناع الإدارة بأن الأمر يستحق مراجعة السيليكون للمراجعة التالية.

ومع ذلك ، سأخصص بعض الوقت لتصميم سيناريوهات قابلة للتكرار حتى يتمكن مهندسو BCM من رؤية المشكلة واختبارها بوضوح. ومع ذلك ، سأعتمد على أعضاء المجتمع هنا لإبلاغ نتائجي إلى Broadcom ؛ ليس لدي قناة لهم.

يجب أن أوضح شيئًا ما حول تعليقي السابق للمجتمع ، حول السيليكون مقابل التغييرات المعدنية.

أنت تعرف كيف ، إذا حصلت على لوحة من SparkFun أو Adafruit ، فغالبًا ما يكون لها آثار يمكنك قطعها أو لحامها معًا لتغيير سلوكها؟ تحتوي معظم لوحات I2C على آثار يمكنك تغييرها لتغيير العنوان أو تمكين أو تعطيل مقاومات السحب ، إلخ.

يقوم مصممو الرقائق الدقيقة بنفس الشيء. هناك الكثير من التغييرات التي يمكنهم إجراؤها على الطبقات المعدنية للرقاقة ، حتى لا يضطروا إلى تغيير طبقات السيليكون. ذلك لأن تغيير طبقات السيليكون أمر صعب ومكلف (مثل تغيير الشريحة على السبورة) ، في حين أن تغيير الطبقات المعدنية أسهل كثيرًا (مثل تغيير الآثار على السبورة).

يمكن إجراء العديد من التغييرات المفيدة في الطبقات المعدنية ، لأن المصممين يفكرون في المستقبل ويقومون بعمل وصلات معدنية (وصلات العبور بشكل أساسي) التي تغير سلوك الشريحة.

ولكن إذا كان هناك تغيير لم يخططوا له ، ولم يتمكنوا من معرفة كيفية إجراؤه عن طريق إعادة توجيه الآثار داخل الشريحة ، فعليهم تغيير السيليكون. يحتاج السيليكون إلى الكثير من التخطيط والتحقق والإخفاء ، لذلك من الصعب تغييره.

العديد من الشركات ، إذا كان لديهم طبقة سيليكون "جيدة بما فيه الكفاية" ، فستستخدمها لأطول فترة ممكنة. سيعيدون استخدام بعض أجزاء طبقة السيليكون في مراجعات متعددة للرقاقة.

أظن أن هذا هو المكان الذي توجد فيه BCM: يحتاجون إلى دليل جيد على أن هذا الخطأ لا يمكن إصلاحه في السائقين أو المعدن قبل أن يتمكنوا من تبرير إعادة هندسة هذا الجزء من طبقة السيليكون من الصفر.

من غير المحتمل للغاية أن يكون هناك تراجع للسيليكون الموجود فقط لإصلاح هذه المشكلة (هل حصلت على مليون دولار احتياطي؟). قد يكون للرقائق المستقبلية حل جيد ، من يدري.

في الأربعاء ، 05 سبتمبر 2018 الساعة 02:13:19 صباحًا -0700 ، كتب جويل راي هولفيك:

يبدو أننا بحاجة إلى بيانات أكثر صلابة ، مثل سيناريوهات repro ، إلى
إقناع Broadcom بإعادة هندسة وحدة التحكم I2C. حتى مع
بيانات صلبة ، سيتعين على المهندسين إقناع الإدارة بذلك
الأمر يستحق مراجعة السيليكون للمراجعة التالية.

لقد أجروا بالفعل ست سنوات و 3 تنقيحات من السيليكون حيث كانوا
أظهروا قرارهم: "لن يتم إصلاحه".

إذا قمت بالتمدد بمقدار> .5 دورة ، فأنت في حالة جيدة.

لا اعتقد هذا. في كل مرة تقوم فيها بتحرير CLK في "قبل
برودكوم يبدو مرة أخرى "فترة زمنية ، تحصل على نبضات قصيرة. يمكنني بسهولة
تأخير إطلاق إشارة الساعة من خلال قول 5 ميكروثانية عديمة الفائدة إلى
يكون دائمًا خارج دورة 0.5. ولكن ذلك لم ينجح.

في الأربعاء 5 سبتمبر 2018 الساعة 02:28:53 صباحًا -0700 صباحًا ، كتب جيمس هيوز:

من غير المحتمل للغاية أن يكون هناك توقف لـ
وجود السيليكون فقط لإصلاح هذه المشكلة (هل حصلت على مليون دولار إضافي؟). مستقبل
الرقائق قد يكون لها الإصلاح رغم ذلك.

انا اشك فيها. انتقلنا من BCM2835 مع علة KNOWN إلى BCM2836 مع
نفس الخطأ إلى BCM2837 مع نفس الخطأ بالضبط إلى BCM2837B0.

الآن لماذا تعتقد أن المراجعة التالية ستكون مختلفة؟

BCM لديها سوق مستهدف: الهواتف وأجهزة التلفزيون لهذه الرقائق. في
لا أحد يقوم بعمل برنامج I2C لأغراض عامة في السوق المستهدف
ميكروكنترولر مثل AVRs و PICs. انهم لن يصلحوا هذا.

إنه لأمر مخز أن هذا الجهد الاستقصائي مطلوب ، رغم أنه أمر رائع. عندما سألت من قبل عن خطأ يغطي هذا ، كان يعتقد أنه لا يوجد خطأ. هل تغير ذلك الآن وهناك عنوان URL؟ من الناحية المثالية ، ستساعد Broadcom المجتمع من خلال وصف الخطأ بدقة وعندما يحدث ، لذا سيكون من الأسهل العمل بثقة على الحلول أو تقييمات المكونات المتوافقة. حتى في حدود مقتطف HDL ذي الصلة إذا كانوا لا يريدون محاولة ترجمة ذلك بدقة إلى وصف.

اقتراح إيقاف مقسوم الساعة نصف بت عند السماح بتمديد الساعة هو اقتراح جيد. سيعمل.

المشكلة في ذلك هي أن الجزء من وحدة I2C سيحتاج بعد ذلك إلى العمل "بسرعة ساعة كاملة". الآن وحدة I2C هي وحدة لطيفة منخفضة الطاقة لأنها لا تعمل بشكل طبيعي أسرع من 200 كيلو هرتز.

السبب الرئيسي لمشاركتي هو ما قلته في بداية رسالتي الأصلية :

أنا ألعب بهذه المشكلة الآن على RPi 3 Model B + ، وأرى نتائج مختلفة عن تلك التي تصفها مقالة Advamation. لم يتم تسريع السيليكون مؤخرًا ، أليس كذلك؟

إذا كان لدينا تغييرات كبيرة على جهاز أو برنامج تشغيل I2C بعد كتابة Advamation 2013 ، ويعرف المجتمع كيف يمكن أن تؤثر على هذا الخطأ ، فعندئذ يجب أن أقوم بإجراء التغييرات المناسبة على تجاربي.

أعلم أن المشكلة الأساسية تكمن في الأجهزة ، ولكن لكل ما أعرفه ، ربما وجد شخص ما من خلال التجربة أن تغيير السجل الذي يبدو أنه ليس له علاقة في برنامج التشغيل يغير بالفعل سلوك هذا الخطأ. لم أقم أيضًا بتأكيد أن BCM2837 لها نفس وحدة I2C مثل RPi 2 (آخر مرة تمكنت فيها من العثور على تأكيد نهائي بأن جهاز I2C لم يتغير منذ الإبلاغ عن هذه المشكلة لأول مرة). لم أجد أيضًا أي معلومات حول أي من خطوات BCM283x ؛ لكل ما أعرفه ، يمكن أن يكون هناك تغيير معدني في عصر BCM2836.

لست مهتمًا بمضايقة Broadcom ، أو التكهن بكيفية تغيير المراجعات المستقبلية ، أو أي شيء من هذا القبيل.

هدفي الأساسي هنا هو توثيق السلوك الحالي بوضوح ؛ يبدو أنه تغير بمرور الوقت. لدي هدف ثانوي للسماح للمستخدمين في المستقبل بإعادة إنتاج تجاربي لمعرفة ما إذا كانت النتائج لا تزال صالحة ، أو لإجراء تحسينات أو اختبار شروط أخرى. لدي هدف ثانوي آخر وهو السماح لمهندسي Broadcom بإعادة إنتاج الاختبارات بسهولة إذا أرادوا ذلك. كلاهما يعني أنني بحاجة لنشر تجاربي ، مما يساعد أيضًا: بسبب غطرستي ، إذا كنت أنشر تجاربي ، فسأكون أكثر حافزًا لجعلها صارمة.

خطتي التجريبية الحالية هي استخدام PIC16F1619 كتنفيذ الرقيق ؛ إنه سريع ومتعدد الاستخدامات بما يكفي لإجراء تجارب إطالة الساعة ، وهو سهل بما يكفي للعمل معه ، وشائع بدرجة كافية بحيث يتمكن المجربون الآخرون من إعادة إنتاج نتائجي. إذا كانت النتائج غامضة ، فقد أقوم أيضًا ببناء تجربة باستخدام FPGA. قد أرى ما إذا كان بإمكاني الحصول على دقة معقولة باستخدام Raspberry Pi آخر في تكوين تقريع بعض الشيء كالعبد ، لكنني أظن أنني سأحتاج إلى شيء بدون نظام تشغيل كامل عليه لإجراء اختبار في الوقت الفعلي.

لمعالجة شيئين آخرين تم طرحهما:

آسف لأن رسالتي الأصلية كانت غير مكتملة ؛ لقد نشرت عن طريق الخطأ مسودة مبكرة. سأتركه كما هو ، لأن التغييرات التي أجريتها طفيفة جدًا.

لا أدعي الأصالة في فكرة إيقاف مقسوم الساعة بينما كان SCL منخفضًا خارجيًا. قرأت ذلك في مكان آخر ، لكن لا أتذكر أين ؛ اعتقدت أنه من Gert van Loo في خيط I2C الذي يمتد على مدار الساعة على raspberrypi.org ، لكن لا يمكنني العثور عليه الآن ، لذلك لا بد أنني رأيت ذلك في مكان آخر. لست مقتنعًا بأنه سيغير ملف تعريف القوة بشكل كبير ،

لم يتم إصلاح / تغيير كتلة I2C HW ، ومن غير المرجح أن تكون كذلك في 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 الثلاثاء 14 أغسطس 17:10:10 بتوقيت جرينتش 2018 armv7l) ونسيت ضبط تردد I2C ولكن لم تظهر الأشباح. حسنًا ، لا أستخدم متحكمًا دقيقًا في الحافلة ، فقط ممدد MEMS و GPIO ، لكني أشعر أن هناك حلًا بديلًا في كود Raspbian's i2c. علاوة على ذلك ، أعتقد أن التسريبات المكتشفة جاءت من ترقية غير كاملة ، فأنا أستخدم نفس البطاقة ولم يتم اكتشاف أي تسريبات.

@ hmf2015 هذه المشكلة تتعلق بمشكلة I2C محددة للغاية. لا تنتج مشاكل بطاقة SD عن مشكلة I2C هذه. إذا كانت بطاقة SD الخاصة بك لا تعمل بشكل صحيح ، فيجب عليك تجربة بطاقة SD جديدة. بعض البطاقات ليست جيدة ، وتتوقف عن العمل بسرعة. توقفت بطاقة SD الخاصة بي عن العمل الشهر الماضي ، واضطررت إلى استبدالها.

عادة ، أشباح I2C ليست بسبب هذه المشكلة. تحدث غالبًا للأسباب التالية:

  • ليس لديك مصدر طاقة جيد. أنا أحب هذا .
  • الكابلات الخاصة بك طويلة جدًا. لا يعمل I2C بشكل جيد مع الكابلات التي يزيد طولها عن متر واحد.
  • الكابلات الخاصة بك لها اقتران سعوي. إذا كان لديك دبابيس I2C (SCL و SDA) ملتوية معًا ، فقد يؤدي ذلك إلى حدوث مشكلة. في بعض الأحيان ، يستخدم الأشخاص كبلات مزدوجة مجدولة (مثل كبلات Ethernet) التي تلوي دبابيس I2C ، وهذا يسبب مشاكل. إذا كان عليك استخدام كبلات مزدوجة مجدولة ، فقم بلف SCL باستخدام Vss (أرضي) و SDA مع Vdd (3.3 فولت). انظر إلى مواصفات I2C في القسم 7.5.
  • جهاز I2C الخاص بك لديه 5 فولت. يقوم Raspberry Pi بعمل I / O بسرعة 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.3V ، لكن المستوى 1 الأدنى أقل.
تحتوي الحزمة BNO055 على منظم جهد كهربائي.
اعتقدت أيضًا أن مشاكل I2C ستكون كما كانت من قبل ، لكنها ليست كذلك ، في الوقت الحالي ليس لدي الوقت (والاهتمام) للنظر في الكود المصدري لـ Raspbian لاكتشاف الاختلافات ، فأنا مهتم في بيئة العمل.
يجب أن تظهر قائمة العناصر فقط ، أنني أعمل في بيئة Andoid (مع نظام Unix حقيقي) حيث يدعم BCM ، وليس باستخدام متحكم دقيق ما أقوم بإرفاقه عبر خط تسلسلي أو USB لأنني كسول. في بيئتك الظروف أكثر تقييدًا من بيئتي ، لذلك لا يمكنني القول ما إذا كانت مشاكلك ستقل ، لكنني آمل.

مرحبًا hmf2015 ،
هذا ليس منتدى. هذا هو تعقب علة. تناقش قائمة التعليقات هذه خطأً لا علاقة له بمشاكلك. يرجى مناقشة مشكلتك مع منتدى مناسب أو مكتب مساعدة. مرة أخرى ، نقدر سؤالك: "ربما هو نفسه؟ ربما يساعد وصفي في حل هذا الخطأ؟" لكننا نعلم الآن على وجه اليقين أن ما تراه ليس له علاقة ، من فضلك لا "تلوث" هذه المناقشة أكثر.

تضمين التغريدة
مرحبًا ، لقد ذكرت منذ وقت طويل مشكلة في جهاز حالة I2C أثناء إعادة التشغيل ونشرت بعض الرموز بخصوص هذه المشكلة.
لست متأكدًا مما تقصده ولكن لدي مشكلة في برنامج الترميز WM8731 المتصل بـ I2C.
بعد 2-3 إعادة تشغيل ، توقف ناقل I2C تمامًا. لا يعرض i2cdetect أي معلومات باستثناء السطر الأول وينقطع الاتصال أيضًا. الطريقة الوحيدة للاسترداد هي دورة خفض الطاقة / لأعلى.
هل هذا يبدو وكأنه القضايا التي ذكرتها؟
أنا أستخدم 4.19 نواة رئيسية.

@ sergey-suloev عندما لا يستمر i2cdetect في المسح بعد 8 أو 16 عنوانًا ، أود أن أقول إن هذا لا علاقة له بهذه المشكلة. تنبثق المشكلة عندما تقوم الأجهزة بتمديد الساعة للإشارة إلى أنها ليست جاهزة بعد لدورة الساعة التالية. عندما تم تصميم I2C منذ ما يقرب من 40 عامًا ، ربما كان ذلك ممكنًا لتطبيقات الأجهزة أيضًا. ولكن في الوقت الحاضر ، تكون الأجهزة جاهزة دائمًا في الوقت المناسب للتعامل مع دورة الساعة التالية لأن 10 ميكروثانية هي أعمار زمنية لشيء يتم تنفيذه في الأجهزة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات