|
|
  |
Глюки с I2C |
|
|
|
Apr 30 2018, 11:33
|
Гуру
     
Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925

|
Цитата(Allregia @ Apr 30 2018, 18:01)  Коллеге, который с этим возится, скоро 60, совсем не студент  Хотя, я больше чем уверен, что где-то какая-то "детская ошибка" сидит. Если Вы не заметили, это вообще не у меня а у коллеги. У меня - "глюк 1", но я с ним пока больше не возился. Так я вам и пишу о детских ошибках. Здесь надо тупо и методично проверять всё - от "ту ли прошивку заливаем", до расчетов регистров на бумажке и проверке дебаггером. А если новым keil компилировали программу, тогда и строки компилятора/линкера сравнить из старого и нового проекта. На pack переходили в проекте или остались на legacy? Телепатов здесь нет, чтобы додумывать что уже сделано, что не сделано, что изменилось в проекте, оборудовании и т.д. А допрашивать лень.....
|
|
|
|
|
Apr 30 2018, 15:08
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Allregia @ Apr 29 2018, 15:12)  Мне тут нужно было в одном относительно старом проекте, который делался на 4-м Кейле, поменять некоторые дефолтные настройки. К I2C оно не относится, но глюк я поймал именно с I2C! Сейчас на компе только 5-й, 4-го нет. Проц - тот-же F103, к нему по I2C подключена 24LC16. У F103 абсюлютно вычурно-глючный I2C. Я на эту тему писал неоднократно, делясь опытом своей борьбы в течение, не вру, недель двух. Итог ее: я победил, но ощущение подставы и подвоха не покидает. Поищи тему с моим ником. Суть выводов: - при работе по прерываниям страсть как не любит быть прерваным: дай прерыванию от I2C наивысший приоритет или обрабатывай определенные куски при глобально запрещенных прерываниях. - что будет стабильно работать при максимальных 72MHz такта процессора, напрочь рушится при, скажем, 24MHz, как правило по причине того, что... - в регистре статуса позможны комбинации битов машины состояния, которые не описаны в доке и не определены во всяких дефайнах! Эти комбинации нужно отслеживать в прерывании в посвященных им ветвям обработчика; при этом для этих комбинаций нельзя просто их проигнорировать, выйти из прерывания и дождаться типа "правильных", а приходится тупо ждать в цикле установки/сброса "лишних" битов. - необходимо особо обрабатывать случаи трансфера только одного или двух байтов, или когда осталось принять два или один байт. - шагать под отладчиком в прерывании I2C - это просто квантовые процессы сродни щелевому эксперименту. Сплошная печаль, короче. Когда мне в руки попался F051, я просто прыгал от восторга, запустив его I2C за часика два (с перерывами на напитки).
|
|
|
|
|
May 1 2018, 04:52
|
Частый гость
 
Группа: Участник
Сообщений: 146
Регистрация: 19-07-16
Пользователь №: 92 603

|
Цитата(KnightIgor @ Apr 30 2018, 21:08)  Сплошная печаль, короче. Когда мне в руки попался F051, я просто прыгал от восторга, запустив его I2C за часика два (с перерывами на напитки). Когда я после ногодрыга для I2C на Z8 впервые запустил аппаратный I2C на STM32L476, то вообще ничего не заметил. :-) Потому что Куб всё сгенерил, я вставил HAL-строки и всё. Память 64К пишется, читается.
|
|
|
|
|
May 1 2018, 10:22
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(serglg @ May 1 2018, 05:52)  Когда я после ногодрыга для I2C на Z8 впервые запустил аппаратный I2C на STM32L476, то вообще ничего не заметил. :-) Потому что Куб всё сгенерил, я вставил HAL-строки и всё. Память 64К пишется, читается. Предыдущая верси той платы, с которой колега возится, была тоже на L476, и никаких проблем с ней небыло. Они начались на новой плате с 452-м. В общем я решил помочь коллеге, и взял пару платок поиграться. Сразу скажу - в отличие от его экспериментов, я не заметил никакой разницы между платаи так и в том запускать под дебаггером или не под дебаггером. Отдал ему результаты. пусть дальше сам возится. Но(!), кое-какие нестыковки я все-же заметил. Причем из серии "этого не может быть, потому что этого не может быть никогда". Поясняю - простенькая программка на калохале, ничего кроме i2c в ней нет. Хал пробовался и 1.8.1 и 1.11.0, разницы в поведении между ними не выявлено. I2C Fast, 400kHz. и обычный на 100кгц. Константу делителя менял вручную. Проверено было 4 варианта источника тактовой - MSI_8MHz, MSI_16MHz, HSI_16MHz, HSE_24MHz. При этом переключался делитель PLLM соответственно 2-4-4-6, т.е. частот на входе PLL была во всех случаях неизменна - 4Мгц. Для контроля, на MCO выводитась частота с текущего источника деленая на 8 дя 8мгц и на 16 для остальных. Остальные настойки не менялись вообще. Каждый источник был проверен 2 раза, с разными константами делителя i2c. В основном цикле, с привязкой к систику (т.е. с периодом 1мс) читался по i2c регистр аккселерометра LSM6DS3. Сразу скажу - цикл 1мс во всех случаях был правильный, в отличие от не совсем точной частоты на MCO и полного балагана с частотой SCL. Просомтр в дебаггере регистров i2c криминала не вявил - что просили, то туда и записалось. Результаты: Код MSI_8: MCO=0.98 MHz, SCL100 = 38 kHz, SCL400 = 155 kHz. MSI_16: MCO=0.987 MHz, SCL100 = 152 kHz, SCL400 = 550 kHz. HSI_16: MCO=0.982 MHz, SCL100 = 140 kHz, SCL400 = 536 kHz. HSE_24: MCO=1.5 MHz, SCL100 = 113 kHz, SCL400 = 425 kHz. Т.е. частота MCO правильная, систика - тоже правильная, а SCK - более-менее правильная только для внешнего кварца. Напомню еще раз - во всех случаях. на входе PLL частота 4мгц, от которой и шло дальнейшее тактирование всего. Менялся только источник этих 4-х мгц. P.S. Да, я понмаю, калокуб и всякое тому подобное, но сгенерированый им исходник ведь не менялся. Тактирование - на вход PLL
|
|
|
|
|
May 1 2018, 10:52
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Allregia @ May 1 2018, 13:22)  . . . . Сразу скажу - цикл 1мс во всех случаях был правильный, в отличие от не совсем точной частоты на MCO и полного балагана с частотой SCL. . . . Насчет "балагана" непонятно. И частоты тоже. SCL характеризуется не частотой, а периодом, тк между фреймами могут быть паузы. Поэтому смотрите период SCL в ждущем режиме. Оптимально - синхрнизировать осц. (в начале приема или передачи блока) от внешнего сигнала, можно ногодрыгом. Намного более удобно пользоваться лог. анализаторм, где есть разборщик протокола I2C, а не рыться в осцилограмме. С лог. анализатором такие слеты вылввливаются "нараз". Для отладки рекомендую Вам прописать в 24LC16 12345 слова по всем адресам (data16 == address) и почитать их с автом. контролем. На запись - в томже стиле.
|
|
|
|
|
May 1 2018, 11:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(ViKo @ May 1 2018, 11:37)  Допустимый диапазон частот на входе PLL описан в документации. И что? Там от 4 до 16, 4Мгц в него не попадает? К тому-же куб бы красным отметил если бы что-то "не то" было. Цитата(k155la3 @ May 1 2018, 11:52)  Насчет "балагана" непонятно. И частоты тоже. SCL характеризуется не частотой, а периодом, А меня 40 лет назал еще в школе учили, что частота это 1/период И задается в I2C обычно именно часто клока (100,400, 1000). Цитата тк между фреймами могут быть паузы. Поэтому смотрите период SCL в ждущем режиме. Оптимально - синхровать осц. (в начале приема или передачи блока) от внешнего сигнала, можно ногодрыгом. Я даже не в "ждущем" а в стопе смотрю, и не то что скоп померял, а меряю сам курсорами. Цитата Намного более удобно пользоваться лог. анализаторм, где есть разборщик протокола I2C, а не рыться в осцилограмме. Смотрел конечно. Он вообщето и в самом осциллографе есть, с таким-же точно "разборщиком протоколов", холтя в данном случае мне было удобнее китайским прибамбасом с Saleae смотреть. Все там в порядке. Да и с передачей данных нет пробем, все корректно читается и пишется (я про глюк №2, 1-й меня сейчас не интересует, им я потом займусь). А дальше все еще чудесатее. Я тут уже как фокусник  Следите за руками: - я в коде, без всяких калокубов меня ДЕЛИТЕЛЬ МСО. который, согласно всем даташитам НЕ ВЛИЯЕТ НИ НА ЧТО, происходящее внутри процессора,. И частота SCL меняется в 2 раза, причем в обратную сторону!. Т.е. при делителе на 8 имеем: MSI_8, DIV=8: MCO=0.98 MHz, SCL100 = 38 kHz, SCL400 = 155 kHz. после изменения делителя на 16 имеем такое: MSI_8, DIV=16: MCO=0.49 MHz, SCL100 = 76 kHz, SCL400 = 310 kHz. вот уж точно - WTF?
|
|
|
|
|
May 1 2018, 11:15
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Allregia @ May 1 2018, 14:05)  И задается в I2C обычно именно часто клока (100,400, 1000). "Обычно"? А кроме куба вы что-то ещё знаете? Обычно - в разных МК по-разному. А ещё - почитайте хоть немного, что такое I2C. И что такое "clock stretching" в нём. Из-за него получаемая на SCL частота, может быть ниже, чем выставляемая через регистры I2C - это вполне нормально. А чтобы проверить правильность выставления частоты, нужно отключить все слэйвы и перевести SCL в push-pull-режим.
|
|
|
|
|
May 1 2018, 11:20
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Allregia @ May 1 2018, 14:05)  . . . .И частота SCL меняется в 2 раза, причем в обратную сторону!. Т.е. при делителе на 8 имеем: MSI_8, DIV=8: MCO=0.98 MHz, SCL100 = 38 kHz, SCL400 = 155 kHz. после изменения делителя на 16 имеем такое: MSI_8, DIV=16: MCO=0.49 MHz, SCL100 = 76 kHz, SCL400 = 310 kHz. . . . . . . . здесь расположены холиврные посты касаемо частоты и периода . . .  Может джиттерр "в особо крупных" ? При PLL его наличие и значение будет зависеть от соотношения частот настройки PLL и опорной частоты. Оптимальній вариант - их кратность. В начале main() (до инициализации) поставьте BP, а лучше - ногодрыг. Если код маленький, то Ваши 1 мс могут прокручивться через ресет, и идет постаянная реинициализация всего.
|
|
|
|
|
May 1 2018, 11:26
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(jcxz @ May 1 2018, 12:15)  "Обычно"? А кроме куба вы что-то ещё знаете? Обычно - в разных МК по-разному. "обычно" - это в стандартах I2C. Цитата А ещё - почитайте хоть немного, что такое I2C. Году в 96-м, переводил я филипсовскую доку по I2C, до сих пор по Сети ходит..... Цитата И что такое "clock stretching" в нём. Из-за него получаемая на SCL частота, может быть ниже, чем выставляемая через регистры I2C - это вполне нормально. "Нормально что", что частота 38 килогерц вместо 100? При слейве, умеющим по даташиту работать на 400, и реально прекрасно работающем и на 550? (на частоту SCL никто бы и не посмотрел бы, если бы незаметили что килобайт даных читается что-то уж больно долго). Или что частота SCL меняется вдвое при изменении делителя выхода MCO? Это тоже "нормально"? Цитата Может джиттерр "в особо крупных" ? а в не особо крупных - не вижу. Цитата При PLL его наличие и значение будет зависеть от соотношения частот настройки PLL и опорной частоты. Оптимальній вариант - их кратность. Так при изменении делителя МСО, все это не менялось. Да оно и при переключении источников клока не менялось!
|
|
|
|
|
May 1 2018, 11:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Allregia @ May 1 2018, 14:26)  . . . . Или что частота SCL меняется вдвое при изменении делителя выхода MCO? Это тоже "нормально"? . . . Захват PLL на (за) границе(ей) , и его прогнозируемый слет. См. док - график частот и допустимых значений коэффициентов. Цитата(Allregia @ May 1 2018, 14:26)  "Да оно и при переключении источников клока не менялось!" Я бы отсюда и начал копать. Без I2C. ps проверить наличие флагов ошибок тактирующей системы.
|
|
|
|
|
May 1 2018, 11:33
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(k155la3 @ May 1 2018, 12:29)  Захват PLL на (за) границе(ей) , и его прогнозируемый слет. См. док - график частот и допустимых значений коэффициентов. Блин, я щас матерится начну, и поверьте - я это умею! Какой нафиг "слет," какой нафиг "за границей"?????? Вы в курсе что такое МСО? Это выход частоты наружу, через отдельный делитель. Эта частота нигде внутри процессора не используется (во всяком случае ничего про это нигде не написано), и сответственно - это делитель ни на что не должен влиять. Сигнал на входе ФАПЧа как был 4мгц, так и остался, как и все его коэффициенты и остальные делители. Цитата Я бы отсюда и начал копать. Без I2C. "Копать" где? Кроме частоты на SCL оно ни на что другое не воздействует.
|
|
|
|
|
May 1 2018, 12:22
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Allregia @ May 1 2018, 14:26)  "обычно" - это в стандартах I2C. Не знаю какие там стандарты в калокубе - не разбираюсь в нём. Но если открыть даташит на первый попавшийся LPC17xx, то можно прочитать: 15:0 SCLH Count for SCL HIGH time period selection.15:0 SCLL Count for SCL low time period selection.Именно период, а не частота. Цитата(Allregia @ May 1 2018, 14:26)  Или что частота SCL меняется вдвое при изменении делителя выхода MCO? Это тоже "нормально"? Что и как там у вас нормально и ненормально - это только вам виднее. И если вы сами не можете отладить свои исходники, то удалённо тут уж точно никто не сможет. Если Вам пишут, что у других на том же МК получается нормальная частота то искать баги стоит у себя, а не искать виноватых вокруг.
|
|
|
|
|
May 1 2018, 12:52
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата(jcxz @ May 1 2018, 13:22)  Если Вам пишут, что у других на том же МК получается нормальная частота то искать баги стоит у себя, а не искать виноватых вокруг. Вас не затруднит привести точную ссылку, где "у других на том же МК получается нормальная частота" ? Цитата(jcxz @ May 1 2018, 13:22)  Не знаю какие там стандарты в калокубе - не разбираюсь в нём. Но если открыть даташит на первый попавшийся LPC17xx, то можно прочитать: А я тоже не знаю что там в калокубе, и описание шины I2C я предопчитаю смотреть в стандартах на нее, а не в описаниях процессоров, даже если это филипсовские процессоры. Можно даже просто в википедию заглянуть: Цитата The history of I²C specification releases: - In 1982, the original 100 kHz I²C system was created as a simple internal bus system for building control electronics with various Philips chips.
- In 1992, Version 1 added 400 kHz Fast-mode (Fm) and a 10-bit addressing mode to increase capacity to 1008 nodes. This was the first standardized version.
- In 1998, Version 2 added 3.4 MHz High-speed mode (Hs) with power-saving requirements for electric voltage and current.
- In 2000, Version 2.1 clarified version 2, without significant functional changes.
- In 2007, Version 3 added 1 MHz Fast-mode plus (Fm+) (using 20 mA drivers), and a device ID mechanism.
- In 2012, Version 4 added 5 MHz Ultra Fast-mode (UFm) for new USDA (data) and USCL (clock) lines using push-pull logic without pull-up resistors, and added an assigned manufacturer ID table. It is only a unidirectional bus.
|
|
|
|
|
May 1 2018, 13:36
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Во многих микроконтроллерах указывается именно период, а не частота I2C. Даже в том же STM32. Использовал I2C в STM32F103, STM32F217, STM32F427 и STM32F429, никаких проблем или нареканий не было, все согласно документации. Осциллографом тыкался - Ровно 100кГц получал на последовательных clock-ах. В режиме контроля clock-stretching между отправляемыми байтами цифровой автомат I2C STM32 вставлял "задержки", отсюда общая частота, замеряемая осциллографом по нескольким сотням пачек - была в 1.5-2 раза меньше, чем 100кГц (запись в EEPROM-память 4-10мс). Главным требованием, из-за несоблюдения которого я промучался довольно долго однажды, это правильная выставка полей предделителя частоты для модуля I2C, а также регистров CCR и TRISE. Там есть ограничения, не помню уже какие. Но когда я ручками выставил все что нужно в эти регистры - все заработало как нужно. Ну а совет сверху очень хороший прозвучал - перевести лапки SCL и SDA в режим push-pull, отключить Slave-устройства от шины и смотреть что на ней. Вот в одном из моих проектов: CODE RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); GPIO_PinAFConfig(GPIO_EXCHANGE_I2C_SCL.GPIO, GPIO_EXCHANGE_I2C_SCL.PinSource, GPIO_AF_I2C1); GPIO_PinAFConfig(GPIO_EXCHANGE_I2C_SDA.GPIO, GPIO_EXCHANGE_I2C_SDA.PinSource, GPIO_AF_I2C1); GPIO_InitTypeDef GPIO_Configure; GPIO_Configure.GPIO_Mode = GPIO_Mode_AF; GPIO_Configure.GPIO_OType = GPIO_OType_OD; GPIO_Configure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Configure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Configure.GPIO_Pin = GPIO_EXCHANGE_I2C_SCL.Pin; GPIO_Init(GPIO_EXCHANGE_I2C_SCL.GPIO, &GPIO_Configure); GPIO_Configure.GPIO_Pin = GPIO_EXCHANGE_I2C_SDA.Pin; GPIO_Init(GPIO_EXCHANGE_I2C_SDA.GPIO, &GPIO_Configure); I2C_InitTypeDef I2C_Configure; I2C_Configure.I2C_ClockSpeed = 100000; I2C_Configure.I2C_Mode = I2C_Mode_I2C; I2C_Configure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_Configure.I2C_OwnAddress1 = HW_EXCHANGE_I2C_ADDRESS_OWN; I2C_Configure.I2C_Ack = I2C_Ack_Enable; I2C_Configure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2C1, &I2C_Configure); I2C1->CCR = 225; I2C1->TRISE = 60; I2C1->FLTR = 0x1F;
I2C_Cmd(I2C1, ENABLE); Частота на APB1 45МГц, PLL заведен от внешнего HSE, fHCLK = 180МГц. fPCLK1 = fHCLK/4 = 45МГц. На выходе I2C получаю 100кГц.
Сообщение отредактировал Arlleex - May 1 2018, 13:42
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|