member
Activity: 62
Merit: 10
That’s way to much work for me…
I just wish there was a way to downgrade from Brains to the old Bitmain FW, can’t do it no matter how i try as some 2 cards work on the older 2017/2018/2019 FW?
There must be a way, i stupidly presumed that when i upgraded to brains that my SSH locked boards that i had to flash to NAND with SD card removed the lock, hence allowing you to downgrade if needed.
I can’t find/see a way to remove Brains?
That’s what bos-toolbox uninstall does, it puts factory fw from 2018 (which has ssh unlocked). sd recovery also works with the S9 family only.
From what you describe, you have a hardware issue. A power fluctuation could easily damage your PSU causing that error.
Various things to check/try, in no specific order:
— Make sure the device is connected to ground at all times (case and psu).
— Check all settings are default (Delete any value, then Save & Apply).
— Try reducing power limit. Wait at least 12 hours for Tuner Status to show Stable.
— Check the cables are well connected, try swapping or replacing them, tighten the power rail screws.
— Disable the hashboard in Configuration > Performance > Override Global Hash Chain about 6 hours.
— Try with another power supply unit, problems with the PSU can also manifest as HW errors.
— Clean the device carefully, if you use liquids you should wait a few days to dry fully.
If the problem persists, it probably has a physical issue that needs repair.
I seldom read other threads (this forum is too large), so you should have listened to what BitMaxz said.
Issue was water damage by the looks.
I definitely need to look inti bos-toolbox, i did download it and did find it somewhat confusing tbh, then after reading on here some where saying it’s main use is for large mining farms, mass flashing/control of 100’s of miners etc and people were doing it simply via SD card, so i went with that and found the process simple and i only have several miner.
Cheers
member
Activity: 62
Merit: 10
I can’t find/see a way to remove Brains?
So you mean the SD card flashing with stock firmware from Bitmain can’t able to replace your current firmware? Or you might just did the wrong way?
If the SD card do not work then try the guide from Braiins documentation. Here check this link below
— FLASHING A FACTORY FIRMWARE
My thinking that the older FW i have (you label it stock -pre brains) is a .tar file and not an image file like Brains.
Brains therefore i can easily flash via SD card, the .tar older FW requires command line or some other process to flash (i’m talking pre BrainsOS 2017 FW etc, the old type Bitmain Fw)
I honestly don’t understand how to do it via the ‘commands’, i presume i use command prompt and manually enter details as it describes, plus i somehow create an image of the .tar file to insert in this command line?
Brains FW already is an image file, so it’s easily created to put on an SD card.
Since so many devices are affected, I would suspect that the there was some kind of voltage peak or similar at your location that damaged your miners. What you now need to find out is what parts are damaged.
It was water damage by the looks, i can now see it and the last two miners i opened that are nearest the cold air input tip garage they are in are were wet, we did have a big storm, power outages etc and a fine mist of water ha entered.
They have sat as they are running for years until this, hence my first thinking was some sort of spike in current/network etc as it was all over the news/social media of big outages locally to me.
That’s way to much work for me…
I just wish there was a way to downgrade from Brains to the old Bitmain FW, can’t do it no matter how i try as some 2 cards work on the older 2017/2018/2019 FW?
There must be a way, i stupidly presumed that when i upgraded to brains that my SSH locked boards that i had to flash to NAND with SD card removed the lock, hence allowing you to downgrade if needed.
I can’t find/see a way to remove Brains?
That’s what bos-toolbox uninstall does, it puts factory fw from 2018 (which has ssh unlocked). sd recovery also works with the S9 family only.
From what you describe, you have a hardware issue. A power fluctuation could easily damage your PSU causing that error.
Various things to check/try, in no specific order:
— Make sure the device is connected to ground at all times (case and psu).
— Check all settings are default (Delete any value, then Save & Apply).
— Try reducing power limit. Wait at least 12 hours for Tuner Status to show Stable.
— Check the cables are well connected, try swapping or replacing them, tighten the power rail screws.
— Disable the hashboard in Configuration > Performance > Override Global Hash Chain about 6 hours.
— Try with another power supply unit, problems with the PSU can also manifest as HW errors.
— Clean the device carefully, if you use liquids you should wait a few days to dry fully.
If the problem persists, it probably has a physical issue that needs repair.
I seldom read other threads (this forum is too large), so you should have listened to what BitMaxz said.
Issue was water damage by the looks.
I definitely need to look inti bos-toolbox, i did download it and did find it somewhat confusing tbh, then after reading on here some where saying it’s main use is for large mining farms, mass flashing/control of 100’s of miners etc and people were doing it simply via SD card, so i went with that and found the process simple and i only have several miner.
Cheers
[moderator’s note: consecutive posts merged]
legendary
Activity: 1596
Merit: 1327
CLEAN non GPL infringing code made in Rust lang
That’s way to much work for me…
I just wish there was a way to downgrade from Brains to the old Bitmain FW, can’t do it no matter how i try as some 2 cards work on the older 2017/2018/2019 FW?
There must be a way, i stupidly presumed that when i upgraded to brains that my SSH locked boards that i had to flash to NAND with SD card removed the lock, hence allowing you to downgrade if needed.
I can’t find/see a way to remove Brains?
That’s what bos-toolbox uninstall does, it puts factory fw from 2018 (which has ssh unlocked). sd recovery also works with the S9 family only.
From what you describe, you have a hardware issue. A power fluctuation could easily damage your PSU causing that error.
Various things to check/try, in no specific order:
— Make sure the device is connected to ground at all times (case and psu).
— Check all settings are default (Delete any value, then Save & Apply).
— Try reducing power limit. Wait at least 12 hours for Tuner Status to show Stable.
— Check the cables are well connected, try swapping or replacing them, tighten the power rail screws.
— Disable the hashboard in Configuration > Performance > Override Global Hash Chain about 6 hours.
— Try with another power supply unit, problems with the PSU can also manifest as HW errors.
— Clean the device carefully, if you use liquids you should wait a few days to dry fully.
If the problem persists, it probably has a physical issue that needs repair.
I seldom read other threads (this forum is too large), so you should have listened to what BitMaxz said.
member
Activity: 62
Merit: 10
@BitMaxz Sorry will edit threads in future.
@philipma1957 ‘I noticed seven of my remote s9 miners ‘
I’ve been trying the hash boards with various cards and FW, with the older fW sometimes very rarely it will recognise a card for a few seconds and ghow a few Gh, then that drops off.
I have then tried known working cards from my miners at home and all is ok.
So i can only determine that all 14 cards have somehow gone faulty? (2 cards/7 miners).
Its odd that BrainsOS recognises the cards, shows testing performance profile shows, but it does not display any hashrate/voltage/freq/asic?
So how can it be testing if its not sending any voltage (or displaying any voltage)?
When tuner then fails i get these messages —
‘Hashchain refused to start
Enumeration: no chips detected on the current chain’
UPDATE 2
Miner is now stable lol —
asics
6 1.181MH/s 161.4GH/s 8.945 V 0.00 °C 0.00 °C 708 MHz 2
8 0.000H/s 484.3GH/s 8.945 V 0.00 °C 0.00 °C 708 MHz 6
1.142MH/s 645.7GH/s 8.945 V 0.00 °C 0.00 °C 708 MHz 8
Fans @ 100%
Or similar to —
‘Hashchain refused to start
Hashchip: number of responses 27 of read_register(reg=0x18) doesn’t match chip count 33: reply 0x36 missing’
Has anyone heard of this before, is there anything else i could try here or have i somehow broken all 14 cards?
There is no surge protection on the supplies, but ive had MCB’s, and plus fuses blow many times without damage to all boards?
Im at a loss here.
Thanks for looking in guys.
edit -Just had 2 cards actually show and a voltage of 9.42v and one card had 400mhz and dropping, plus one board showed 2 asics, the other 1 asic.
As i’m watching and ‘tuner’ is running the one board is 40mhz and dropping to 0…..
member
Activity: 62
Merit: 10
Hi
I noticed seven of my remote s9 miners were off online and when i looked up there was an internet fault in the area that lasted 14 hurs outage. (Virgin Media) and never had problems before)
I have just been to location and some were just ticking over/not mining, some where totally dead so i checked main 13a fuses and they had blown?
I replaced them/tried new leads and had 3 go BANG when the PSU’s blew?
I now have 2 miners that i am running, but both are just ticking over and getting tuner failed, there is not any voltage being displayed on monitir screen when it tries to tune either?
Plus sometimes i get this error message -‘Hashchain refused to start I2C error’, sometimes i do not, plus its random on 2 miners.
All are running BrainsOS+ and are a mixture of cards that i know brains does not like……But i updated them to Brains a few weeks ago and all has seen fine since this outage.
I have brought 5 miners to my location on my network now and i’m fetting the same results??
Any ideas?
I’m running one now at mine at its TUNER FAILED but it did not even display any hashrate/voltage/frequency/asics???
Don’t knwo where to start here tbh… But i know Brains does not like mixing control boards/cards and this is what these miners are….
I have older model control bards here and i bet the one i’m thinking that if i fit an old board with old Bitmain FW it would boot up…
Anyone help please….
Thanks
ЛОГ:
Asic[25]:650 Asic[26]:650 Asic[27]:650 Asic[28]:650 Asic[29]:650 Asic[30]:650 Asic[31]:650 Asic[32]:650
Asic[33]:650 Asic[34]:650 Asic[35]:650 Asic[36]:650 Asic[37]:650 Asic[38]:650 Asic[39]:650 Asic[40]:650
Asic[41]:650 Asic[42]:650 Asic[43]:650 Asic[44]:650 Asic[45]:650 Asic[46]:650 Asic[47]:650 Asic[48]:650
Asic[49]:650 Asic[50]:650 Asic[51]:650 Asic[52]:650 Asic[53]:650 Asic[54]:650 Asic[55]:650 Asic[56]:650
Asic[57]:650 Asic[58]:650 Asic[59]:650 Asic[60]:650 Asic[61]:650 Asic[62]:650
Chain:5 max freq=650
Chain:5 min freq=650
read PIC voltage=940 on chain[6]
Chain:6 chipnum=63
Asic[ 0]:650
Asic[ 1]:650 Asic[ 2]:650 Asic[ 3]:650 Asic[ 4]:650 Asic[ 5]:650 Asic[ 6]:650 Asic[ 7]:650 Asic[ 8]:650
Asic[ 9]:650 Asic[10]:650 Asic[11]:650 Asic[12]:650 Asic[13]:650 Asic[14]:650 Asic[15]:650 Asic[16]:650
Asic[17]:650 Asic[18]:650 Asic[19]:650 Asic[20]:650 Asic[21]:650 Asic[22]:650 Asic[23]:650 Asic[24]:650
Asic[25]:650 Asic[26]:650 Asic[27]:650 Asic[28]:650 Asic[29]:650 Asic[30]:650 Asic[31]:650 Asic[32]:650
Asic[33]:650 Asic[34]:650 Asic[35]:650 Asic[36]:650 Asic[37]:650 Asic[38]:650 Asic[39]:650 Asic[40]:650
Asic[41]:650 Asic[42]:650 Asic[43]:650 Asic[44]:650 Asic[45]:650 Asic[46]:650 Asic[47]:650 Asic[48]:650
Asic[49]:650 Asic[50]:650 Asic[51]:650 Asic[52]:650 Asic[53]:650 Asic[54]:650 Asic[55]:650 Asic[56]:650
Asic[57]:650 Asic[58]:650 Asic[59]:650 Asic[60]:650 Asic[61]:650 Asic[62]:650
Chain:6 max freq=650
Chain:6 min freq=650
read PIC voltage=940 on chain[7]
Chain:7 chipnum=63
Asic[ 0]:650
Asic[ 1]:650 Asic[ 2]:650 Asic[ 3]:650 Asic[ 4]:650 Asic[ 5]:650 Asic[ 6]:650 Asic[ 7]:650 Asic[ 8]:650
Asic[ 9]:650 Asic[10]:650 Asic[11]:650 Asic[12]:650 Asic[13]:650 Asic[14]:650 Asic[15]:650 Asic[16]:650
Asic[17]:650 Asic[18]:650 Asic[19]:650 Asic[20]:650 Asic[21]:650 Asic[22]:650 Asic[23]:650 Asic[24]:650
Asic[25]:650 Asic[26]:650 Asic[27]:650 Asic[28]:650 Asic[29]:650 Asic[30]:650 Asic[31]:650 Asic[32]:650
Asic[33]:650 Asic[34]:650 Asic[35]:650 Asic[36]:650 Asic[37]:650 Asic[38]:650 Asic[39]:650 Asic[40]:650
Asic[41]:650 Asic[42]:650 Asic[43]:650 Asic[44]:650 Asic[45]:650 Asic[46]:650 Asic[47]:650 Asic[48]:650
Asic[49]:650 Asic[50]:650 Asic[51]:650 Asic[52]:650 Asic[53]:650 Asic[54]:650 Asic[55]:650 Asic[56]:650
Asic[57]:650 Asic[58]:650 Asic[59]:650 Asic[60]:650 Asic[61]:650 Asic[62]:650
Chain:7 max freq=650
Chain:7 min freq=650
max freq = 650
set baud=1
Chain[J6] PIC temp offset=62,0,0,0,0,0,35,28
Chain[J6] chip[244] use PIC middle temp offset=0 typeID=55
New offset Chain[5] chip[244] local:26 remote:27 offset:29
Chain[J6] chip[244] get middle temp offset=29 typeID=55
Chain[J6] chip[136] use PIC middle temp offset=28 typeID=00
Warning: Chain[J6] has no temp offset in PIC! will fix it
New offset Chain[5] chip[244] local:26 remote:28 offset:28
Chain[J6] chip[244] get middle temp offset=28 typeID=55
Chain[J7] PIC temp offset=62,0,0,0,0,0,35,28
Chain[J7] chip[244] use PIC middle temp offset=0 typeID=55
New offset Chain[6] chip[244] local:26 remote:31 offset:25
Chain[J7] chip[244] get middle temp offset=25 typeID=55
Chain[J7] chip[136] use PIC middle temp offset=28 typeID=00
Warning: Chain[J7] has no temp offset in PIC! will fix it
New offset Chain[6] chip[244] local:27 remote:31 offset:26
Chain[J7] chip[244] get middle temp offset=26 typeID=55
Chain[J8] PIC temp offset=62,0,0,0,0,0,35,28
Chain[J8] chip[244] use PIC middle temp offset=0 typeID=55
New offset Chain[7] chip[244] local:27 remote:30 offset:27
Chain[J8] chip[244] get middle temp offset=27 typeID=55
Chain[J8] chip[136] use PIC middle temp offset=28 typeID=00
Warning: Chain[J8] has no temp offset in PIC! will fix it
New offset Chain[7] chip[244] local:27 remote:29 offset:28
Chain[J8] chip[244] get middle temp offset=28 typeID=55
Chain[J6] set working voltage=880 [108]
Chain[J7] set working voltage=880 [108]
Chain[J8] set working voltage=880 [108]
setStartTimePoint total_tv_start_sys=71 total_tv_end_sys=72
restartNum = 2 , auto-reinit enabled…
do read_temp_func once…
do check_asic_reg 0x08
get RT hashrate from Chain[5]: (asic index start from 1-63)
get RT hashrate from Chain[6]: (asic index start from 1-63)
get RT hashrate from Chain[7]: (asic index start from 1-63)
Check Chain[J6] ASIC RT error: (asic index start from 1-63)
Check Chain[J7] ASIC RT error: (asic index start from 1-63)
Check Chain[J8] ASIC RT error: (asic index start from 1-63)
Done check_asic_reg
do read temp on Chain[5]
Chain[5] Chip[62] TempTypeID=55 middle offset=28
read failed, old value: Chain[5] Chip[62] local Temp=0
read failed on Chain[5] Chip[62] middle Temp old value:0
Done read temp on Chain[5]
do read temp on Chain[6]
Chain[6] Chip[62] TempTypeID=55 middle offset=26
read failed, old value: Chain[6] Chip[62] local Temp=0
read failed on Chain[6] Chip[62] middle Temp old value:0
Done read temp on Chain[6]
do read temp on Chain[7]
Chain[7] Chip[62] TempTypeID=55 middle offset=28
read failed, old value: Chain[7] Chip[62] local Temp=0
read failed on Chain[7] Chip[62] middle Temp old value:0
Done read temp on Chain[7]
set FAN speed according to: temp_highest=0 temp_top1[PWM_T]=0 temp_top1[TEMP_POS_LOCAL]=0 temp_change=0 fix_fan_steps=0
set full FAN speed…
FAN PWM: 100
read_temp_func Done!
CRC error counter=0
Ошибка по шине i2c
Поиск неисправностей в системной шине I 2 C
Напряжение питания как к линии SDA , так и к линии SCL подводится через нагрузочные резисторы. Значение этого напряжения обычно составляет от 4,5 В до 5,5 В и должно точно соответствовать приведенному в сервисной документации уровню. Поиск неисправностей, поэтому следует начинать с измерения питающего шину напряжения. К прекращению обмена информацией в шине могут привести также колебания питающего напряжения питания, особенно в тех случаях, когда появляется какая-нибудь нерегулярная неисправность. Пульсации могут составлять всего лишь несколько милливольт, поэтому в сомнительных случаях проверку питающего системную шину напряжения надо проводить с помощью осоцилографа.
Обычно на входах блоков, подключаемых к системной шине, или перед микросхемами в этих блоках располагают еще и развязывающие резисторы. С помощью измерения напряжения на этих резисторах можно установить наличие короткого замыкания в соответствующем блоке. Если такая неисправность присутствует, то измеренное напряжение на выводе резистора, со стороны подключенного блока или микросхемы, имеет существенно более низкое значение, чем на другом выводе резистора. Если же в проверяемых узлах короткое замыкание отсутствует, то падение амплитуды сигнала на соответствующих развязывающих резисторах незначительное из-за достаточно низкого их номинала (от 100 Ом до 1 кОм). Поиск неисправностей усложняется, когда отдельные узлы и схемы подключены к системной шине без развязывающих резисторов, так как в этом случае любой неисправный узел может полностью заблокировать обмен информацией по системной шине. В этом случае придется последовательно отсоединять подключенные к шине отдельные узлы и схемы.
Уже измерение напряжения до и после нагрузочных резисторов может дать указание на вероятную неисправность в одном из устройств, подключенных к системной шине, если падение напряжения на этих резисторах слишком велико.
Необходима также проверка наличия сигналов в линиях SCL и SDA шины. Отсутствие сигнала синхронизации в линии SCL указывает на необходимость проверки работоспособности центрального управляющего устройства, а также внешнего кварцевого резонатора тактового генератора ЦУУ. Неисправности частотозадающих элементов тактового генератора могут быть причиной отличия тактовой частоты от номинальной, что также может привести к нарушению обмена информацией в шине.
Тактовый сигнал может представлять собой синусоидальный сигнал, либо сигнал прямоугольной или трапециевидной формы.
Наличие импульсных сигналов номинальной амплитуды в линии SDA -шины само по себе не дает достоверной информации о правильности обмена данными между узлами ВМ, подключенными к системной шине, но при их наличии можно условно считать, что обмен данными в системе происходит правильно.
Источник
Обработка ошибок и перезапуск модуля I2C
Сегодня в комментариях меня попросили рассмотреть работу I2C более подробно, обратить внимание на нетривиальные случаи: например, что будет в случае возникновения ошибок на линии, как такие ошибки обрабатывать? Дело в том, что при появлении таких ошибок модуль I2C часто «зависает», и не реагирует на дальнейшие обращения — нужно ловить такую ситуацию и перезапускать модуль.
Стандартная процедура общения с I2C-модулем предусматривает отправку байт и проверку флага — передано или нет. Флаг проверяется в цикле while, и именно этот цикл подвержен зависаниям — если флаг не устанавливается из-за ошибки, из этого цикла мы уже не выйдем никогда.
Я предлагаю простой способ выхода из этой ситуации — вместо простого while нужно сделать «while с условием». К примеру, если цикл опроса флага безрезультатно прокрутился более 200 раз — наверное ситуация уже не изменится, т.к. возникла ошибка. Значит нужно перезагружать модуль I2C.
Сделать это просто: добавим переменную «таймаут» = 200, и в цикле опроса флага будем её декрементировать. Как только она дошла до нуля — сбрасываем текущую передачу и перезапускаем модуль. Очень важно именно отменить передачу, потому что иначе после перезапуска модуля она продолжится с того места, где застряла в прошлый раз — ну и ни к чему хорошему это не приведёт.
Код примера, демонстрирующего эту «безопасную передачу», таков:
И в заключение пару слов, почему я сделал именно так, ведь более логичным было бы добавление прерываний на ошибки и обработка этих прерываний. Я просто хотел как можно меньше менять исходный код, сделать это проще всего оказалось именно расширив стандартный while до такого «while с таймаутом». Более того, так можно обойтись без глобальных переменных, а это всегда очень хорошо.
Введение обработчиков прерываний ошибок раздуло бы код и спрятало бы основную логику. Мне это неудобно. Кстати, подобная проблема встречалась у меня при работе микроконтроллера LM3S с RFID-ридером, я думаю такой подход решил бы её.
Источник
Многобукфф
Vladislav’s personal blog site
Нестабильная работа с I2C под STM32
Волею судеб мне пришлось разрабатывать прошивку для одного устройства на основе микроконтроллера STM32F103. Функций у устройства много, в том числе и общение с EEPROM подключенным посредством протокола I 2 C. Кто не знает, микроконтроллеры STM32 во многих своих версиях поддерживают работу по данному протоколу на аппаратном уровне. Это значит, что у микросхемы микроконтроллера присутствуют специальные выводы, которые можно использовать в том числе и для работы по протоколу I 2 C, а все издержки по этому протоколу выполняются «железом» микроконтроллера.
Вообще, I 2 C — штука популярная. Реализуется не так сложно, для его работы требуется всего два сигнальных провода. По одному подаются тактовые импульсы, по второму происходит передача данных, привязанная к тактам первого провода. К шире или выводам I 2 C можно подключить несколько устройств, они не будут мешать друг-другу, т.к. при обращении к конкретному устройству указывается его уникальный адрес.
Шина I 2 C не высокоскоростная и предназначена в первую очередь для обмена данными с различными датчиками, модулями и внешними системами. Через шину прокачать много информации не выйдет, но этого и не требуется. Главное, что она проста, дешева и универсальна. Ну много ли данных передает в секунду датчик температуры или давления? Сущие байты. Этого вполне достаточно.
Как правило в шине I 2 C применяется система с одним ведущим устройством и подключаемыми к нему ведомыми. В качестве ведущего устройства, разумеется, используется микроконтроллер. И он опрашивает подключенные устройства, в надежде получить с них данные. Каким же образом передаются данные по-фактически одному проводу? Конечно, передача данных по одному проводу в I 2 C не является полнодуплексной. Нет возможности в стандарте по одному проводу передавать и принимать данные одновременно. Поэтому, команды на передачу дает ведущее устройство, а все остальные слушают и отвечают, когда это им позволяется.
Простота протокола I 2 C иногда оборачивается и обратной стороной. Отлаживать проблемы, возникающие в коммуникации с внешними устройствами зачастую очень не просто. Ведь в цифровом мире либо устройство работает, либо нет. А еще больше усложняет проблему случай, когда вроде бы работает, а потом, по какой-то причине не совсем работает. Вот именно такая петрушка и произошла в моем случае.
Для реализации микропрограммы был выбран фреймворк STM32Arduino, так как требовалось использовать некоторые библиотеки, которые легче взять готовые, нежели разрабатывать их заново. К чипу же STM32 подключена обычная микросхема EEPROM на несколько килобит. EEPROM используется для частых записей, для чего не предназначена Flash-память на чипе STM32. Все аппаратные подключения проведены в строгом соответствии с документацией как производителя микроконтроллера, так и микросхемы EEPROM. И именно проверка того, как сделаны аппаратные подключения, надежно ли питание, есть ли все необходимые подтяжки и прочее, должна происходить в самую первую очередь, если возникла проблема. Иначе можно потратить годы на то, чтобы найти программную причину ошибки, особенно там, где ее нет.
В моем случае проблема заключалась в выдаче недостоверных результатов с EEPROM и невозможность записи. Точнее запись проходила, но на конечный осмысленный результат они никак не влияла. Причем неполадка появлялась только после аппаратного перезапуска устройства и примерно один раз из десяти. Присутствие какой-либо адекватной реакции от всех программах слоев, на которые опирается STM32Duino ожидать не стоит. I 2 C протокол простой и он либо работает, либо нет. И он работал, выдавал данные, причем даже если данные с EEPROM приходили откровенно левые, то никакие ошибки обращения с библиотекой Wire не возникало. Пришлось начать копать интернет в поисках похожих ошибок и методов их решения.
Как оказалось, проблема при работе с I 2 C на чипах STM32, особенно семейства F103, возникает чуть ли не у каждого второго пользователя чипов. Причем независимо от того, на чем он пишет свой код: HAL, Arduino, Mbed или еще чего. Проблем возникает много, у кого-то ничего не работает сразу, что несколько легче, так как искать ошибку проще, а у других все работает из коробки, но не постоянно. Основные проблемы, на которые натыкаются пользователи кроются в некоторых, назовем их так, особенностях структуры чипов STM32F10x, да ошибках, которые присутствуют в HAL.
Приведу основные причины возникновения неполадок с I 2 C, полученные после изучения «всего интернета»:
- Ненадежное аппаратное подключение, ненадежное неверное питание, несоблюдение рекомендаций по подключению.
- Блокировка шины на стороне микроконтроллера со статусом Busy.
- Перепутанные выходы, перепутанная инициализация при добавлении второго канала I 2 C на многоканальных чипах. Ошибка из серии «Я скопировал оттуда, где работало, а тут не работает».
Кстати, последняя ошибка встречается не столько при простом копировании кода, завязанного на работу через I 2 C, а сколько на его инициализацию. STM32 штука сложная и если невнимательно работать с Cube или писать инициализацию своими руками, то наверняка куда-то может затесаться мизерная ошибочка, которую замыленный глаз уже не в состоянии разглядеть. Вторая же ошибка по большей части связана с неверной (а зачастую с бездумной) инициализацией микроконтроллера, но присутствуют и особенности реализации (читай ошибки) в самом чипе. С ними (обнаруженными и признанными) и объясняется что делать в замечательном документе Errata sheet (ссылка внизу статьи).
В общем наилучшее, что мог создать коллективный разум, это код принудительной переинициализации функции I 2 C через HAL с дополнительными задержками:
/* 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 */
В Arduino на STM32 данный блок так же можно применить, но он не помогает, по крайней мере, в моем случае. Пришлось еще немного пораскинуть мозгами и попытаться докопаться до причины проблемы, а потом попытаться ее решить. В моем случае обмен данными с EEPROM по I 2 C идет без каких-либо проблем. Данные читаются, записываются, никаких ошибок не возникает. Только вот в одном разе из 10 после аппаратной перезагрузки всей системы, EEPROM начинает выдавать совершенно левые данные, при этом никаких ошибок не возникает. С записью тоже в такие моменты не все гладко, проверить-то никак.
Как известно, чипы STM32 многофункциональны и многие из выводов микросхем могут быть использованы под различные функции. У многих микроконтроллеров, не только у STM32, после перезагрузки, некоторые выводы могут переключиться в так называемые неинициализированные состояния. Обычный софтверный разработчик, как правило не задумывается над тем, какой у него уровень на выводах микроконтроллера после его перезагрузки. Высокий? Низкий? Серединный? При использовании фирменного конфигуратора STM32Cube есть возможность настроить инициализацию выводов и некоторых других функций микроконтроллера путем относительно простого конфигурирования. Но данная процедура может быть опущена, а инициализацию можно провести позже, например, при процедуре вызова той или иной функции. Именно последним путем и пошли разработчики STM32Duino. При загрузке микроконтроллера происходит так называемая базовая инициализация функций микроконтроллера, ножки выводов принимают значения по умолчанию. А вот если с данной конкретной ножки требуется другая функция, то ее инициализация происходит при первом вызове соответствующей функции.
В чипах STM32 инициализация происходит очень быстро, ну сами чипы скоростные, это, во-первых, а во-вторых, загрузчик не тормозит загрузку пользовательского кода, так как вызывается при соответствующей аппаратной комбинации. Значит, проблема неинициализированных «ног», когда на них болтается неизвестно что, встает не в полный рост. А вот на других чипах микроконтроллеров, где загрузчик некоторое время ожидает подачу ему сигнала и только потом переходит на пользовательский код, проблема может существенно попортить жизнь. Представьте, что на такой «ноге», которая еще не определилась с уровнем своего сигнала, «висит» управляющий контакт реле. И вот на реле идет жуткая последовательность непонятных сигналов. Что ему делать? Дергаться туда-сюда, пока микроконтроллер не определиться со своим выводом?
Опытный читатель или электронщик, уже догадался, в чем изюминка порылась. Микросхема EEPROM возвращает неверные данные, а библиотека, работающая с I 2 C, говорит, что все нормально, ошибок нет. Суть нестабильного поведения кроется в следующем. На универсальных чипах STM32F103 многие из выводов многофункциональны. При неверной инициализации или отсутствии инициализации, на «ногах», подключенных к микросхеме EEPROM, может появиться произвольный сигнал, который «сведет с ума» саму микросхему EEPROM (команды на обмен данными с EEPROM та еще китайская азбука, куча условностей, задержек и прочего). Да, она будет как-то реагировать на команды, но вот выдавать данные может совсем не те, что должна. Повторная инициализация I 2 C в микроконтроллере ничего не даст, так как ведомое устройство уже не в себе и вывести его из себя можно только аппаратной перезагрузкой микросхемы EEPROM (перезагрузка микроконтроллера тут не помогает, по той же причине, что и переинициализация через HAL).
Именно такая ситуация возникла в моем случае. Проблема возникала случайным образом, но статистически она присутствовала. Если код инициализации Wire поместить ближе к началу программного кода, то вероятность возникновения ошибки уменьшается, если отодвинуть его куда-то подальше, то ошибка будет возникать чаще. И спастись от проблемы можно только аппаратным сбросом всего оборудования (передергиванием питания).
Так как же можно избавиться от проблемы «сумасшествия» ведомой микросхемы EEPROM? Очевидно, что нужно максимально быстро проинициализировать соответствующие терминалы ввода-вывода, дабы успеть в тот момент времени, пока EEPROM не начнет жить по своим собственным законам, повинуясь непонятным сигналам с микроконтроллера. Другими словами, подвинуть код инициализации Wire в самое начало программы. Но… Данный трюк не решает полностью описанное поведение EEPROM. Все еще остается вероятность отказа EEPROM (и опыты это подтверждают). Почему? Потому, что выполнение кода инициализации Wire занимает какое-то время, бесценные микросекунды, которых хватает на то, чтоб EEPROM удалились в мир грез и фантазий. Что в этом случае можно сделать?
pinMode(I2C_SCL, OUTPUT);
pinMode(I2C_SDA, OUTPUT);
Оказалось, что достаточно только проинициализировать порты микроконтроллера, ответственные за I 2 C как выходные цифровые выводы, как можно быстрее. В этом случае цифровое, а скорее аналоговое, шатание отменяется и невменяемость EEPROM тоже. В STM32Duino при инициализации пина как выходящего, он автоматически включается на низкий уровень. Если этого не происходит, например, поменялась идеология разработчиков фреймворка или вышла новая плата, на которой все не так, то дополнительно можно принудительно установить низкий уровень, что должно обеспечить нормальную работоспособность всей связки.
А что же до любителей HAL и особенно STM32Cube? Если работать только на HAL и не прибегать к Cube, как к средству конфигурирования, то проблема будет ровно такой же. Если не применить четкую инициализацию «ног» I 2 C как можно быстрее, то нормально с EEPROM не поработаешь. Впрочем, с Cube тоже не все так гладко как хотелось бы. Да, утилита помогает провести инициализацию микроконтроллера, которая сама по себе не отличается простотой. Но и тут могут быть нюансы. Во-первых, код инициализации I 2 C из Cube может быть выполнен в самую последнюю очередь, когда уже поздно, во-вторых, могут наступить и прочие конфликты, связанные с неверной инициализацией (Cube только выглядит просто, на самом деле без понимания туда лезть не стоит). Более подробно о потенциальных проблемах можно почитать в ссылках ниже.
- STM32 WRITE AND READ EEPROM OVER I2C BUS — статья детально разжевывающая методы обращения с EEPROM подключенным посредством I 2 C.
- STM32F10xx8 STM32F10xxB Errata sheet (medium-density device limitations) — бюллетень от STMicroelectronics описывающий возможные затруднения и способы борьбы с ними по различным блокам своих микроконтроллеров. Проблем работы с I 2 C в документе указано аж 7.
- STM32 — I2C — HAL_BUSY — статья что делать, если возникает Busy.
Опубликовано 12.09.2020 автором kvv в следующих категориях:
DIYSoftстатья
Источник
The imp API provides users of I²C peripheral devices (‘peripherals’) with debugging information following failed attempts to read or write data to any I²C peripheral connected to an imp. This information comes in the form of an integer constant returned by either i2c.write() or i2c.readerror(), depending on the type of operation being performed. If either method returns any value other than 0, an error has occurred. The return value indicates the nature of the error, and these errors are listed in the i2c.readerror() documentation. Should an error occur, the I²C transaction is abandoned.
This document describes these errors in more detail. They are presented in the order in which they are likely to be encountered, with those relating to write operations appearing first, followed by those issued during read operations.
The imp API makes sending and receiving data via I²C very straightforward, but ‘under the hood’ the process as is complex. As such, a single imp API I²C access may result in any one of a series of errors, depending on which stage of the process the underlying impOS™ I²C code has reached.
The I²C Protocol
Developers working with imp005-based devices should note that the following applies primarily to other imp devices. The imp005’s Broadcom SoC will report only two I²C error values: -13 and -9. The former is as described below, but the latter covers almost all of the remaining I²C errors: unfortunately, some error conditions aren’t reported at all (success is falsely indicated). We hope to improve imp005 I²C error reporting in a future version of impOS.
The Errors
Not Enabled (-13)
This is a straightforward error that is issued when you have attempted to access an imp I²C bus that has not yet been configured. Check your code and, if necessary, call i2c.configure() with a supported speed constant passed as a parameter.
Controller Select Error (-1)
The imp signals its intention to begin an I²C transaction by establishing the standard I²C start condition: it attempts to pull the SDA line low (so the waveform has a falling edge) while the SCL line remains high. If the imp is unable to pull SDA low, this error will be issued.
This error may arise if another I²C master is operating on the same bus and has taken control of it. If the imp is the only master on the bus, this error may result from poorly chosen pull-up resistors. I²C ports are open drain so can only pull the SDA and SCL lines low; pull-up resistors are required to drive the lines high when they are released by bus devices.
Transmit Select Error (-2)
After the imp has signalled start and is ready to write data to it, it sends the 7-bit address of the I²C peripheral it wants to communicate with, followed by a single bit indicating whether the transaction is a write (the imp pulls SDA low) or a read (the imp leaves SDA high). These eight bits should be acknowledged by a single-bit ACK signal from the peripheral at the transmitted address; it pulls SDA low. If the acknowledgement doesn’t occur during the ninth clock pulse, then the imp will issue this error.
If this error is encountered, check the value of the peripheral’s address that you are passing. Some devices have multiple addresses, selectable by setting an address pin to one of three states (high, low or floating). The imp API takes addresses in 8-bit form; 7-bit addresses will need to be bit-shifted left one place.
Transmit Error (-3)
BTF Error (-4)
Once the peripheral has acknowledged its readiness, the imp can begin to send the data it wants to write. Data is sent byte by byte, each one written to the imp’s data register from which it is passed to a shift register and from there out onto the bus one bit at a time. Once the peripheral has clocked in a byte of data, it should acknowledged receipt. If it fails to do so while the imp is processing any byte of the data but the last, a transmit error will be issued. If the error occurs sending the last byte, a BTF error is reported instead.
A transmit error may also be reported if the bit value clocked out is not seen on the bus, ie. the imp sends a 1, ie. it leaves the SDA line high, but the SDA line is pulled low. This could indicate bus contention — there is another master on the bus — or, more likely, that the I²C circuit’s pull-up resistors are too weak to keep the lines high.
Stop Error (-5)
Once the imp has successfully written all the data it wants to send to the peripheral (or read back all the data that it requested), it signals the completion of the transaction with a stop condition: while SCL is high, SDA is released to go high too (the waveform has a rising edge). This releases the bus for other devices to make use of it. Again, the imp checks that this stop signal has been sent correctly. If it has not, then this error will be issued.
Address Clear Error (-6)
During a read operation, the imp places on the bus the I²C address of the peripheral it wants to read data from. This event should be acknowledged by the peripheral. If it is not, the imp will return this error.
Address RXNE Error (-7)
Data RXNE Error (-8)
Controller Receive Select Error (-10)
Receive Error (-11)
BTF Receive Error (-14)
All of these errors indicate a failure to read a byte from the peripheral at some point during the read operation. This is often caused by the peripheral holding the SCL line low while it retrieves the requested byte(s) — a technique called ‘clock stretching’.
Which error you get will depend on the number of bytes you have requested to be read and on the exact point where the receive error occurred.
Reselect Error (-12)
If the imp wishes to read data from a specific peripheral register, it must first write that register’s address to the peripheral as a data value. After the register address has successfully been written, the imp initiates a read operation, to pick up the value the peripheral returns from the register. The imp switches from write mode to read mode by issuing a second start signal. Once again, it checks that it can proceed. If it is unable to do so within the timeout period, this error will be issued.
Current Behavior
My config is Matek F722-STD powered by Matek FCHUB-6S. After connecting the board to Inav configurator (first powered by battery) I’m getting i2c errors of 45 and in tasks lists max load is exceeding 100% for battery task.
Here is dump of CLI for my board:
version
INAV/MATEKF722 2.1.0 Feb 25 2019 / 16:59:54 (65b0ec1)
GCC-7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
status
System Uptime: 65 seconds
Current Time: 2041-06-28T01:04:00.000+00:00
Voltage: 16.88V (4S battery — OK)
CPU Clock=216MHz, GYRO=MPU6500, ACC=MPU6500, BARO=BMP280, MAG=HMC5883
STM32 system clocks:
SYSCLK = 216 MHz
HCLK = 216 MHz
PCLK1 = 54 MHz
PCLK2 = 108 MHz
Sensor status: GYRO=OK, ACC=OK, MAG=OK, BARO=OK, RANGEFINDER=NONE, OPFLOW=NONE, GPS=OK
SD card: Manufacturer 0x2, 15126528kB, 06/2016, v2.4, ‘SA16G’
Filesystem: Ready
Stack size: 6144, Stack address: 0x20010000, Heap available: 1664
I2C Errors: 45, config size: 4671, max available config: 16384
ADC channel usage:
BATTERY : configured = ADC 1, used = ADC 1
RSSI : configured = ADC 3, used = none
CURRENT : configured = ADC 2, used = ADC 2
AIRSPEED : configured = none, used = none
System load: 6, cycle time: 509, PID rate: 1964, RX rate: 49, System rate: 9
Arming disabled flags: ANGLE NAV RX CLI
tasks
Task list rate/hz max/us avg/us maxload avgload total/ms
0 — SYSTEM 9 3329 4 3.4% 0.5% 24374
1 — GYRO/PID 1960 160 132 31.8% 26.3% 28619
2 — RX 49 53 41 0.7% 0.7% 237
3 — SERIAL 100 687 5 7.3% 0.5% 110
4 — BATTERY 49 40053 17 196.7% 0.5% 134
5 — TEMPERATURE 99 12 3 0.6% 0.5% 28
6 — BEEPER 99 10 4 0.5% 0.5% 48
7 — GPS 49 260 26 1.7% 0.6% 140
8 — COMPASS 9 226 219 0.7% 0.6% 245
9 — BARO 43 241 159 1.5% 1.1% 765
13 — TELEMETRY 498 17 4 1.3% 0.6% 269
16 — OSD 248 1053 44 26.6% 1.5% 1209
17 — CMS 49 5 2 0.5% 0.5% 10
20 — VTXCTRL 4 4 1 0.5% 0.5% 0
Task check function 6 2 11
Total (excluding SERIAL) 266.5% 34.4%
bootlog
Time Evt Description Parameters
3: 0 CONFIG_LOADED
3: 1 SYSTEM_INIT_DONE
259: 19 TIMER_CHANNEL_MAPPED (1, 1, 0, 2)
259: 19 TIMER_CHANNEL_MAPPED (2, 2, 0, 2)
259: 19 TIMER_CHANNEL_MAPPED (3, 3, 0, 2)
259: 19 TIMER_CHANNEL_MAPPED (4, 4, 0, 2)
259: 19 TIMER_CHANNEL_MAPPED (5, 5, 0, 2)
259: 19 TIMER_CHANNEL_MAPPED (6, 6, 0, 2)
259: 2 PWM_INIT_DONE
759: 21 TEMP_SENSOR_DETECTION
960: 9 GYRO_DETECTION (7, 0, 0, 0)
1451: 10 ACC_DETECTION (8, 0, 0, 0)
1552: 11 BARO_DETECTION (4, 0, 0, 0)
1552: 20 PITOT_DETECTION (0, 0, 0, 0)
1562: 12 MAG_DETECTION (2, 0, 0, 0)
1673: 21 TEMP_SENSOR_DETECTION
2080: 13 RANGEFINDER_DETECTION (0, 0, 0, 0)
2080: 4 SENSOR_INIT_DONE
2633: 5 GPS_INIT_DONE
2633: 7 TELEMETRY_INIT_DONE
3634: 8 SYSTEM_READY
resource
IO:
A00: SERIAL4 UART TX
A01: SERIAL4 UART RX
A02: FREE
A03: SERIAL2 UART RX
A04: FREE
A05: SPI1 SCK
A06: SPI1 MISO
A07: SPI1 MOSI
A08: MOTOR6 OUT
A09: SERIAL1 UART TX
A10: SERIAL1 UART RX
A11: USB IN
A12: USB OUT
A13: FREE
A14: LED2 OUT
A15: FREE
B00: FREE
B01: MOTOR5 OUT
B02: FREE
B03: SPI3 SCK
B04: SPI3 MISO
B05: SPI3 MOSI
B06: I2C1 SCL
B07: I2C1 SDA
B08: FREE
B09: LED1 OUT
B10: OSD CS
B11: FREE
B12: FREE
B13: SPI2 SCK
B14: SPI2 MISO
B15:
SPI2 MOSI
C00: ADC CH1
C01: SDCARD CS
C02: MPU CS
C03: MPU EXTI
C04: ADC CH2
C05: FREE
C06: MOTOR1 OUT
C07: MOTOR2 OUT
C08: MOTOR3 OUT
C09: MOTOR4 OUT
C10: FREE
C11: FREE
C12: FREE
C13: BEEPER OUT
C14: FREE
C15: FREE
D02: FREE
Entering CLI Mode, type ‘exit’ to return, or ‘help’
diff
version
INAV/MATEKF722 2.1.0 Feb 25 2019 / 16:59:54 (65b0ec1)
GCC-7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
resources
mixer
mmix 0 1.000 -1.000 1.000 -1.000
mmix 1 1.000 -1.000 -1.000 1.000
mmix 2 1.000 1.000 1.000 1.000
mmix 3 1.000 1.000 -1.000 -1.000
servo mix
servo
feature
feature -AIRMODE
feature THR_VBAT_COMP
feature BAT_PROF_AUTOSWITCH
feature GPS
feature PWM_OUTPUT_ENABLE
beeper
map
map TAER
serial
serial 3 2 115200 115200 0 115200
led
color
mode_color
aux
aux 0 1 0 900 1250
aux 1 2 0 1300 1700
aux 2 26 0 1300 2100
aux 3 4 3 925 1250
aux 4 3 2 900 1700
aux 5 9 2 900 1275
aux 6 8 4 1700 2100
aux 7 19 1 900 1300
aux 8 21 4 900 1300
adjrange
rxrange
temp_sensor
osd_layout
osd_layout 0 0 23 1 V
osd_layout 0 1 1 12 V
osd_layout 0 2 0 0 V
osd_layout 0 4 8 6 H
osd_layout 0 11 1 10 V
osd_layout 0 12 1 11 V
osd_layout 0 13 23 6 V
osd_layout 0 14 1 1 V
osd_layout 0 15 23 5 V
osd_layout 0 30 2 13 V
osd_layout 0 34 10 1 V
osd_layout 0 44 0 0 V
master
set looptime = 500
set gyro_hardware_lpf = 256HZ
set gyro_lpf_hz = 90
set gyro_notch1_hz = 200
set gyro_notch1_cutoff = 100
set acc_hardware = MPU6500
set acczero_x = 19
set acczero_y = 2
set acczero_z = 11
set accgain_x = 4085
set accgain_y = 4083
set accgain_z = 4100
set align_mag = CW270FLIP
set mag_hardware = HMC5883
set magzero_x = 46
set magzero_y = -171
set magzero_z = 91
set baro_hardware = BMP280
set pitot_hardware = NONE
set rssi_channel = 12
set serialrx_provider = SUMD
set sdcard_detect_inverted = ON
set motor_pwm_rate = 2000
set motor_pwm_protocol = MULTISHOT
set current_meter_scale = 179
set model_preview_type = 3
set gps_provider = UBLOX7
set gps_sbas_mode = EGNOS
set inav_reset_altitude = EACH_ARM
set inav_w_z_baro_p = 0.350
set nav_rth_altitude = 3000
profile
profile 1
set mc_p_pitch = 43
set mc_i_pitch = 40
set mc_d_pitch = 20
set mc_p_roll = 43
set mc_i_roll = 40
set mc_d_roll = 20
set mc_p_yaw = 70
set dterm_lpf_hz = 80
set dterm_notch_hz = 200
set dterm_notch_cutoff = 100
set roll_rate = 50
set pitch_rate = 50
set yaw_rate = 45
battery_profile
battery_profile 1
set battery_capacity = 2200
Добрый день.
Разные версии прошивок, разные модули SFP и SFP+. (прошивки от 7.02.B028 до 7.03.B046)
Периодически зависают порты как SFP так и SFP+, отключение-включение портов восстанавливает линк(периодичность разная раз в неделю или несколько раз в месяц, может зависнуть 1-2 порта могут все 28).
Подскажите возможное решение данной проблемы.
# Power Saving
config power_saving mode led disable
config power_saving mode port disable
config power_saving mode hibernation disable
config power_saving mode link_detection disable
# DDM
config ddm power_unit dbm
config ddm ports 1-28 state disable
config ddm ports 1-28 shutdown none
с порта #27_1210-28xsme подключен порт #25(второго)_1210-28xsme
DGS-1210-28XS/ME:5# sh ddm po 27 st
Command: show ddm ports 27 status
Port Temperature Voltage Bias-Current TX-Power RX-Power
(in Celsius) (Volts) (mA) (Dbm) (Dbm)
—— ————— ——— ————— ———- ———-
27 +66.660 3.07 23.6 -8.2 -7.7
Port State/ Settings Connection Address Auto
Type MDI Speed/Duplex/FlowCtrl Speed/Duplex/FlowCtrl Learning Downgrade
—— ——- ——————— ——————— ——— ———
25 Enabled Auto/Disabled 1000M/Full/Disabled Enabled Disabled
N/A
26 Enabled Auto/Disabled 1000M/Full/Disabled Enabled Disabled
N/A
27 Enabled Auto/Disabled Link Down Enabled Disabled
N/A
28 Enabled Auto/Disabled 1000M/Full/Disabled Enabled Disabled
N/A
в sw1 нет линка к sw2 хотя уровни есть (порт 27 sw1)
tech support v7.03.B046:
30/08/2022 09:29:42 [I2C] ERROR[NP]: soc_i2c_read_byte_data(devno:0x51,addr:0x60) failed for: Operation timed out
30/08/2022 09:29:42 [I2C] ERROR[NP]: soc_i2c_read_byte_data(devno:0x51,addr:0x60) failed for: Operation timed out
30/08/2022 09:29:42 [I2C] ERROR[NP]: soc_i2c_read_byte_data(devno:0x51,addr:0x60) failed for: Operation timed out
30/08/2022 09:29:42 [I2C] ERROR[NP]: soc_i2c_read_byte_data(devno:0x51,addr:0x60) failed for: Operation timed out
30/08/2022 09:29:42 [I2C] ERROR[NP]: soc_i2c_read_byte_data(devno:0x51,addr:0x60) failed for: Operation timed out
30/08/2022 09:29:42 [I2C] ERROR[NP]: soc_i2c_read_byte_data(devno:0x51,addr:0x60) failed for: Operation timed out
I2C SFP Device ErrorCount : 2
I2C Other Device ErrorCount : 92679
tech support v7.02.B028:
— I2C Info. —
I2C Device ErrorCount
———— ————
SFP 158262
Other 35517
Еще в логах линк падаетподнимается:
359 Aug 30 08:50:28:LinkStatus-6: Port 15 link up, 1Gbps FULL duplex
356 Aug 30 08:50:28:LinkStatus-6: port 15 link down
355 Aug 30 08:50:27:LinkStatus-6: Port 15 1000 GBIC module detected.
348 Aug 30 08:33:53:LinkStatus-6: Port 25 link up, 1Gbps FULL duplex
344 Aug 30 08:33:52:LinkStatus-6: port 25 link down
343 Aug 30 08:33:52:LinkStatus-6: Port 25 1000 GBIC module detected.
Последний раз редактировалось spawn13 Вт авг 30, 2022 10:15, всего редактировалось 1 раз.
-
fly135
- Posts: 606
- Joined: Wed Jan 03, 2018 8:33 pm
- Location: Orlando, FL
Re: error when trying to use I2C
mzimmers wrote:Well, my HW guys have checked out the board and say it looks OK, so I’m inclined to think I’m doing something wrong.
Here’s a code snippet of my attempt to implement the protocol described in the drawing in my above post.
Code: Select all
m_i2c_cmd = i2c_cmd_link_create(); ESP_ERROR_CHECK(i2c_master_start(m_i2c_cmd)); ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, (uint8_t) ((devAddr) | I2C_MASTER_READ), true)); ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, (uint8_t) regAddr, true)); ESP_ERROR_CHECK(i2c_master_read(m_i2c_cmd, data, 2, I2C_MASTER_LAST_NACK)) ESP_ERROR_CHECK(i2c_master_stop(m_i2c_cmd)); err = (i2c_master_cmd_begin(I2C_PORT_NBR, m_i2c_cmd, 100));
Does anything jump out at you as wrong here?
Thanks.
i2c_master_write_byte(m_i2c_cmd, (uint8_t) ((devAddr << 1) | I2C_MASTER_READ), true)
-
mzimmers
- Posts: 643
- Joined: Wed Mar 07, 2018 11:54 pm
- Location: USA
Re: error when trying to use I2C
Postby mzimmers » Tue Nov 06, 2018 6:53 pm
Hi Fly —
It took me some time to figure out the Maxim datasheet, but I believe that their addresses are «pre-shifted.»
Slave Addresses
Charger: 0xD2/D3h
Clogic, GTEST and Safeout LDOs: 0xCCh/0xCDh
Fuel Gauge: 0x6C/0x6D. See the Fuel Gauge I2C Protocol for details in the Fuel Gauge section.
I believe that, in the example of the fuel gauge, the address is really 0x6c >> 1. When you want to write, you use 0x6c; when you want to read, you use 0x6d (I hope that made sense).
I’ve managed to get this much working (and by «working» I mean not producing a timeout error):
Code: Select all
esp_err_t PowerMgr::i2cRead(uint8_t devAddr, uint8_t regAddr, uint8_t *data)
{
esp_err_t err;
uint8_t addrRead, addrWrite;
// note about data (address) field: the ESP32 docs say to shift addresses one bit to the left,
// but it appears that the addresses supplied in the MAX77818 data sheet already have been shifted.
// keep this in mind when setting addresses from the datasheet.
addrRead = static_cast<uint8_t>(((devAddr) | I2C_MASTER_READ));
addrWrite = static_cast<uint8_t>(((devAddr) | I2C_MASTER_WRITE));
m_i2c_cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(m_i2c_cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, addrWrite, true));
ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, regAddr, true));
//ESP_ERROR_CHECK(i2c_master_read(m_i2c_cmd, data, 1, I2C_MASTER_LAST_NACK))
ESP_ERROR_CHECK(i2c_master_stop(m_i2c_cmd));
err = (i2c_master_cmd_begin(I2C_PORT_NBR, m_i2c_cmd, 100));
if (err == ESP_OK)
{
ESP_LOGI(TAG, "i2cRead(): i2c_master_cmd_begin() successful.");
}
else
{
ESP_LOGE(TAG, "i2cRead(): error %x on i2c_master_cmd_begin.", err);
}
i2c_cmd_link_delete(m_i2c_cmd);
return err;
}
If I uncomment the i2c_master_read line, then I get a time out. I’m sure it’s my doing; I’m still trying to understand the protocol of the Maxim device. I am curious, though, how I’m supposed to introduce the read address into my code.
-
mzimmers
- Posts: 643
- Joined: Wed Mar 07, 2018 11:54 pm
- Location: USA
Re: error when trying to use I2C
Postby mzimmers » Tue Nov 06, 2018 7:13 pm
I think I’m slowly getting to the bottom of this…this code works:
Code: Select all
addrRead = static_cast<uint8_t>(((devAddr) | I2C_MASTER_READ));
addrWrite = static_cast<uint8_t>(((devAddr) | I2C_MASTER_WRITE));
m_i2c_cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(m_i2c_cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, addrWrite, true));
ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, regAddr, true));
ESP_ERROR_CHECK(i2c_master_start(m_i2c_cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(m_i2c_cmd, addrRead, true));
ESP_ERROR_CHECK(i2c_master_read(m_i2c_cmd, data, 1, I2C_MASTER_LAST_NACK))
ESP_ERROR_CHECK(i2c_master_stop(m_i2c_cmd));
err = (i2c_master_cmd_begin(I2C_PORT_NBR, m_i2c_cmd, 100));
I think this is observing the protocol in the diagram…notice the extra i2c_master_start() call in the middle of the sequence. Seems weird, but at least it returns without error.
Now…to see if I can actually read the registers…
-
mikemoy
- Posts: 559
- Joined: Fri Jan 12, 2018 9:10 pm
Re: error when trying to use I2C
Postby mikemoy » Tue Nov 06, 2018 8:32 pm
Here is how I read a byte, and later how i read a word.
Code: Select all
esp_err_t readByte(uint8_t icAddress, uint8_t registerAddress, uint8_t *data)
{
esp_err_t espRc;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, icAddress << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, registerAddress, ACK_CHECK_EN);
// Setup the read
i2c_master_start(cmd);
i2c_master_write_byte(cmd, icAddress << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, data, NACK_VAL);
i2c_master_stop(cmd);
// Shoot it out
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return espRc;
}
Read Word
Code: Select all
esp_err_t readWord(uint8_t icAddress, uint8_t registerAddress, uint16_t *data)
{
esp_err_t espRc;
uint8_t msb, lsb;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, icAddress << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, registerAddress, ACK_CHECK_EN);
// Setup the read
i2c_master_start(cmd);
i2c_master_write_byte(cmd, icAddress << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &msb, ACK_VAL);
i2c_master_read_byte(cmd, &lsb, NACK_VAL);
i2c_master_stop(cmd);
// Shoot it out
espRc = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
*data = (uint16_t)( (msb << 8) | lsb );
return espRc;
}
-
mzimmers
- Posts: 643
- Joined: Wed Mar 07, 2018 11:54 pm
- Location: USA
Re: error when trying to use I2C
Postby mzimmers » Tue Nov 06, 2018 8:45 pm
Interesting…your read protocol includes that master_start in the middle of the message, too. Maybe that’s not as unusual as I thought. Of course, my memory is probably somewhat faded; the last time I did any I2C stuff, Bush was president…
I’m still not sure I trust the readings I’m getting, but more experimentation will tell.
-
mikemoy
- Posts: 559
- Joined: Fri Jan 12, 2018 9:10 pm
Re: error when trying to use I2C
Postby mikemoy » Tue Nov 06, 2018 8:53 pm
ya… when it comes to reading you first write to the chip basically telling it Hey, i want to read from this register next, then you issue the restart, because if you’d issue a stop, you would have effectively told the chip were done, which we are not yet. After the restart, then you issue the read I.E. «READ_BIT» . then when your done you issue the stop to complete the process.
-
fly135
- Posts: 606
- Joined: Wed Jan 03, 2018 8:33 pm
- Location: Orlando, FL
Re: error when trying to use I2C
Postby fly135 » Tue Nov 06, 2018 9:48 pm
mzimmers wrote:Interesting…your read protocol includes that master_start in the middle of the message, too. Maybe that’s not as unusual as I thought. Of course, my memory is probably somewhat faded; the last time I did any I2C stuff, Bush was president…
I’m still not sure I trust the readings I’m getting, but more experimentation will tell.
I had to look into this some more. I’m using some wrapper code that another consultant wrote for the company before I signed on. I also looked at the IDF docs. I noticed that the IDF docs example for a read doesn’t set the sub-address, and doesn’t have the two starts.
https://docs.espressif.com/projects/esp … e4ce9f.png
You have the two starts and my wrapper code has it as well because you are programming the sub-address before the read.
John
-
mzimmers
- Posts: 643
- Joined: Wed Mar 07, 2018 11:54 pm
- Location: USA
Re: error when trying to use I2C
Postby mzimmers » Tue Nov 06, 2018 9:53 pm
Hi John — yeah, that made it a bit of a challenge to map the ESP calls to the Maxim device protocol. Fortunately, staring at the Maxim drawing long enough eventually got it to sink in. What you’re referring to as sub-addresses are called «registers» in the Maxim data sheet. Not all I2C devices have multiple registers, I guess, and the example in the ESP docs is a rather simple one.
-
fly135
- Posts: 606
- Joined: Wed Jan 03, 2018 8:33 pm
- Location: Orlando, FL
Re: error when trying to use I2C
Postby fly135 » Tue Nov 06, 2018 10:01 pm
mzimmers wrote:Hi John — yeah, that made it a bit of a challenge to map the ESP calls to the Maxim device protocol. Fortunately, staring at the Maxim drawing long enough eventually got it to sink in. What you’re referring to as sub-addresses are called «registers» in the Maxim data sheet. Not all I2C devices have multiple registers, I guess, and the example in the ESP docs is a rather simple one.
Seems like every I2C chip I’ve used had registers. The docs probably would be more helpful if the example had them as well.
John A
-
mzimmers
- Posts: 643
- Joined: Wed Mar 07, 2018 11:54 pm
- Location: USA
Re: (solved) error when trying to use I2C
Postby mzimmers » Tue Dec 18, 2018 4:30 pm
Well, I’m seeing problems with my I2C again. This might be due to hardware changes, but I thought I’d post here to see if anyone had an idea on what might be going on.
My call to i2c_master_cmd_begin() is returning ESP_ERR_TIMEOUT. There are 3 instances of this return code in the routine, but I traced my occurrence to here (beginning at line 1271 in 3.1.1):
Code: Select all
portBASE_TYPE evt_res = xQueueReceive(p_i2c->cmd_evt_queue, &evt, wait_time);
if (evt_res == pdTRUE) {
if (evt.type == I2C_CMD_EVT_DONE) {
if (p_i2c->status == I2C_STATUS_TIMEOUT) {
// If the I2C slave are powered off or the SDA/SCL are connected to ground, for example,
// I2C hw FSM would get stuck in wrong state, we have to reset the I2C module in this case.
i2c_hw_fsm_reset(i2c_num);
clear_bus_cnt = 0;
ret = ESP_ERR_TIMEOUT;
I should point out that my calls return (almost) immediately, even though I specify a relatively long wait time. Again, it’s very possible that this is due to a hardware error of some kind, but based on what I’ve posted, does anyone have an idea what might be happening?
Thanks…
Who is online
Users browsing this forum: No registered users and 40 guests