Удаленное управление. I2C. Сломаный акселерометр.
-
Приветствую!
Сегодня я расскажу, как на ferro_remote удаленно сделать i2cdump. i2cdump это мелкая утилита, которая берет номер шины I2C, адрес устройства и дампит на консоль значения всех его регистров.
Для примера я возьму акселерометр на чипе mma7660fc. К большому сожалению девайс издох, и поэтому показывает всякую хрень вместо нормальных значений. Хотя есть вариант, что я что-то не так сделал с подключением. Но так как раньше он работал исправно, считаю, что он сломан. Но не важно. Сломаность акселерометра не мешает показать работу i2cdump.
Я уже его воткнул, включил (установка 7 регистра в значение 1) и делаю штатный вызов на самой распберри: 0x4c - адрес устройства (можно получить при помощи i2cdetect, например)
$ sudo i2cdump -y 1 0x4c No size specified (using byte-data access) 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 18 18 18 18 18 18 18 18 18 18 18 18 57 17 17 17 ????????????W??? 10: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 ???????????????? 20: 17 17 17 18 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? 30: 18 18 18 18 18 18 18 18 18 18 18 18 17 17 17 17 ???????????????? 40: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 ???????????????? 50: 17 17 17 17 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? 60: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? 70: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? 80: 18 18 18 18 18 18 18 19 19 19 19 19 19 19 19 19 ???????????????? 90: 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 ???????????????? a0: 19 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? b0: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? c0: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ???????????????? d0: 18 58 17 17 17 17 17 17 17 17 17 17 17 19 19 19 ?X?????????????? e0: 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 ???????????????? f0: 19 19 19 19 18 18 18 18 18 18 18 18 18 18 18 18 ????????????????
Как видно в регистрах мусор. А раньше там были вполне годные данные.
Вот теперь такую же картинку я получу при помощи lua_client с малины.
И так скрипт, который считает данные с устройства
i2c = fr.client.smbus -- алиас function main( ) local dev = assert(i2c.open(1, 0x4c)) -- откроем шину и установим адрес 0x4c local request = { } -- таблица с запросом. См. пояснение после кода. for i=0, 255 do table.insert( request, i ) -- таблица просто содержит значения от 0 до 255 end local dump = assert(dev:read_bytes( request )) -- вызов. если он успешен, -- в dump мы получим таблицу, в которой будут записаны значения каждого регистра. while i < 256 do -- просто выведем все значения print( i, " = ", dump[i] ) i = i + 1 end end
Про таблицу в запросе read_bytes.
Так как вызов у меня не локальный (я читаю с удаленной системы), у меня есть возможность запросить сразу несколько значений регистров устройства за один вызов, чтоб делать меньше запросов к удаленной системе. Можно спрашивать по одному, но это будет медленнее.
Данный, не слишком длинный и сложный код, читает и выводит значения всех регистров устройства.
$ ./lua_client -s 192.168.1.11:12345 -e i2cdump.lua 0 = 23 1 = 23 2 = 23 ......... skipped ....... 254 = 24 255 = 24
Собственно это все, что от него требовалось, но, немного прикрутив форматирование:
i2c = fr.client.smbus function main( ) local dev = assert(i2c.open(1, 0x4c)) local request = {} for i=0, 255 do table.insert( request, i ) end local dump = assert(dev:read_bytes( request )) -- выведем красивую табличку с hex значениями io.write( " 0 1 2 3 4 5 6 7 8 9 a b c d e f", " 0123456789abcdef\n") local i, r, str = 0, 0, "" io.write( "00: " ) while i < 256 do local b = dump[i] io.write( string.format('%02X ', b ) ) str = str..string.char(b) i = i + 1 if i % 16 == 0 then r = r + 16 io.write( ' ', str:gsub('%c','.'), '\n' ) str = "" if i < 256 then io.write( string.format('%02X: ', r ) ) end end end end
Всё! Получили почти аналог i2cdump.
PS:
$ ./lua_client -s 192.168.1.11:12345 -e i2cdump.lua 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ................ 10: 18 18 18 16 16 16 16 16 16 16 16 16 16 16 16 16 ................ 20: 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 ................ 30: 16 16 16 16 16 57 17 17 17 17 17 17 17 17 17 17 .....W.......... 40: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 ................ 50: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 ................ 60: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 ................ 70: 17 17 17 17 17 17 17 17 17 17 19 19 19 19 19 19 ................ 80: 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 ................ 90: 19 19 19 19 19 19 19 19 19 19 19 19 17 17 17 17 ................ A0: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 ................ B0: 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 18 ................ C0: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ................ D0: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ................ E0: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ................ F0: 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 ................