bobbjenkins

I2C иногда выдает HAL_BUSY после включения

5 сообщений в этой теме

bobbjenkins    5

Привет

Иногда, например сразу после прошивки контроллера (STM32F103), HAL_I2C_Mem_Read/HAL_I2C_Mem_Write возвращают HAL_BUSY. Но, если перезагрузить контроллер - все начинает работать. Иногда после перезагрузки кнопкой на плате i2c с этим i2c устройством не заводится, приходится заводить его как мопед - с нескольких перезагрузок reset'ом. Такое зависание обычно бывает, если зажать кнопку RESET и подержать секунду - сама плата с stm32 стартует нормально, а устройство I2c не работает, хотя зависания i2c случаются и при кратковременном резете.

Приаттачены настройки I2c из куба и отрывок из Datasheet I2C устройства (гироскоп/акселерометр MPU9250). Как думаете, в чем может быть причина? Подтягивающие резисторы (sda-vcc, scl-vcc), разумеется, на самой плате имеются.

Что я пробовал сделать (ничего из этого не помогло): 

1) добавлял HAL_Delay(1000) при старте STM32

2) также при старте добавил  (mpu9250 подключен к i2c1)

__HAL_RCC_I2C1_FORCE_RESET();
HAL_Delay(1000);
__HAL_RCC_I2C1_RELEASE_RESET();

3) менял настройки i2c в кубе: выставил StandardMode/1khz (хотя по спецификации, MPU9250 поддерживает i2c 4кгц).

В самом протоколе I2c, к сожалению, недостаточно хорошо разбираюсь, чтобы понять, что может происходить...

Screen Shot 2017-08-16 at 9.24.37 AM.png

Screen Shot 2017-08-16 at 9.27.57 AM.png

 

Изменено пользователем bobbjenkins

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


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
mail_robot    1 166

для начала посмотрите в каком случае вообще возникает HAL_BUSY. Скорее всего контроллер не получает ACK от устройства в заданный интервал времени. Такое может быть, если "абонент" хочет, чтобы его слегка "дернули", после старта. Достаточно для этого сделать просто пустой WRITE на любой прерываемой функцией HAL_I2C с таймаутом (например миллисекунду). Просто по адресу пулять например чтение статуса или ID устройства, до тех пор пока не ответит, игнорируя ошибки чтения по таймауту.

У этих акселерометров вечно такие проблемы со связью. Контроллер бывает и не виноват вовсе.

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


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

Спасибо за ответ.

Нашел совет вот здесь: https://community.st.com/thread/15632. Судя по всему - это баг в реализации HAL для F10* контроллеров.

Рекомендуют включать тактирование i2c вручную (в обход куба) перед инициализацией gpio, + установить/сбросить бит RESET у i2c. 

Добавил вот этот код в начало main(), перед инициализацией периферии:

  /* USER CODE BEGIN SysInit */
   __HAL_RCC_I2C1_CLK_ENABLE();
   HAL_Delay(100);
   __HAL_RCC_I2C1_FORCE_RESET();
   HAL_Delay(100);
   __HAL_RCC_I2C1_RELEASE_RESET();
   HAL_Delay(100);
  
  /* USER CODE END SysInit */

Пока что нет (и, надеюсь, не будет) проблем с BUSY, независимо от длительности перезагрузки.

HAL_Delay'и здесь не нужны, верно?

Update: Как оказалось, задержки нужны. Без них, при длительном зажатии кнопки Reset, HAL_BUSY появлялись. Кстати и сейчас изредка появляются, но очень редко и при зажатии ресета на несколько секунд. Но работать можно. Вот такой костыль...

Изменено пользователем bobbjenkins

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


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

думаю нет

можно было попробовать просто инитки местами поменять и все в начале main()

Изменено пользователем mail_robot

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


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

Оказывается, проблема еще глубже. Если кому-то интересно, в эррата есть подробное описание решения:

"I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry" 

 

http://www.st.com/content/ccc/resource/technical/document/errata_sheet/7d/02/75/64/17/fc/4d/fd/CD00190234.pdf/files/CD00190234.pdf/jcr:content/translations/en.CD00190234.pdf#page26

 

Там приводятся 15 шагов по обходу этой проблемы

И еще вот решения:

https://electronics.stackexchange.com/questions/272427/stm32-busy-flag-is-set-after-i2c-initialization

https://electronics.stackexchange.com/questions/267972/i2c-busy-flag-strange-behaviour

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

Изменено пользователем bobbjenkins

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


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

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

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

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

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

Загрузка...