Удаленное управление. 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    ................
  • 0

Комментарии (0)

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.