Да, у Pavia там опечатка и явно не хватает буквы h. Отличия же в моем коде связаны с языком С++ или С. На первое выдается warning Хотя чисто логически я сейчас разницы не вижу. 1й код как я заметил под отладчиком работает не совсем корректно, видимо операция не равно не выполняется. У меня 7 бит устанавливается, поэтому этот код работает, но в него надо внести еще проверку ошибки устройства и проверки таймаута.
Особенности языка Си. Разработчики языка по неясной причине сделали приоритет побитовых операторов (включая &) ниже, чем операторов сравнения (включая !=). Так что условие в первом коде компилятор интерпретирует как Status & (0x80 != 0x80), что совсем не то, что нужно (и превращается в Status & 0, то есть 0). Иногда дико раздражает.
Гм,гм,гм..... поднадоедать стали в топиках эти SMBusЫ-колбасы уже )))))) Пора бы правду изыскать, хлопчики, ведь все дадено вроде, короче стряхнул пыль со своих сорцов по интелу и поскольку Protorus оказался типа собрат по чипсету SB700, а PDF гуглится на раз-два http://developer.amd.com/assets/43009_sb7xx_rrg_pub_1.00.pdf... вот зацепило манёха, взял и поправил свою читалку SPDшников и теперь она v.1.2 и собсссвеннно помимо интелов (на всех и вся я не проверял, конечно) теперь и AMD SB700 у меня зачитывает. Во всяком случае серийные номера планок, что дает CPU-Z все точно байт в байт у обоих и на тех адресах. Кто жаждет и жаждАет на свой страх и типа риск может пускануть сие творение http://rghost.ru/2488871, ТОЧКА!
В общем с SPD я разобрался. Меня теперь интересует батарейка ноутбука. У кого нибудь есть сорцы по этой теме или хотя бы пример работы по протоколу SMBus командами READ/WRITE WORD & BLOCK READ/WRITE? Просто у меня не получается совместить в мозгу протокол описанный в спецификации и реально используемые регистры контроллера SMBus, я не вижу между ними никакой связи.... Какие регистры надо использовать, почему и как это организуется не понятно... И еще вопрос: при использовании Receive Byte для чтения SMBus в спецификации указано, что передается 7 бит адреса, бит направления, потом адрес ячейки памяти. Тогда откуда бурется 3й байт 48h,который записывается в регистр SMBus base + 2?
если говорить лично обо мне, то я тебе это уже дал и ткнул туда несколько раз..... тебе осталось посидеть и покорпеть с даташитом с карандашом и бумажкой, чтобы все "устаканилось" в голове. значит не изучал, не вкуривал архитектуру матери, чипсета, картинки никогда не смотрел, на шины между и между не обращал внимания. Если кратко - не заморачивайся, твоя ближайшая задача изучить южный мост по данному вопросу, а SMBus тебе надо просто понимать, что такое типа ьам живет, и оно медленное хозяйство, да еще и однопроводное...... между и между. доверься изучению сорцов + даташита на южник, сопоставь наконец в мозгу каждый этап где IN, OUT и каков адрес с одной строны в исходнике и где это дело в доке, как она обзывается, описывается, какие биты имеет, что из этого получается 48h или 4Сh, например если побитно превратить в хекс - ВСЕ СОЙДЕТСЯ, УВЕРЯЮ! вот НуНа так и точка! Для начала именно так и понимай... Ты НЕ доверяешь производителям биоса и их ДИЗАССЕМБЛУ что ли? НУ процедура подготовительная такая в южнике, инициализационная, предварительная, допустим, так понятно? ЧИТАЙ, СОПОСТАВЛЯЙ, все дадено!!!!!!!!!!!!!!!!!!! Попыхти, тебе же на пользу. Успехов!
Хм, чего-то подобного я и ждал, причем практически слово в слово)) и сидел весь день вкуривал маны. Кстати шина 2проводная. Я понял откуда берется 48h и прочая дребедень, правда с регистрами остался чуток, но раньше-позже осилю. После прокуривания я написал следующий код: Код (Text): void ReadBatteryStatus( int SMBusBase ) { //попробуем считать температуру батареи printf("\nRead battery data "); //цикл по ячейкам SPD ClearSMBusStatusReg(SMBusBase); //пишем адрес и направление команды в регистр Transmit Slave Address - батарейка 0001 011b и чтение 1 _outp(SMBusBase+4, 0x17); //пишем код команды в регистр команды контроллера SMBus - чтение статуса _outp(SMBusBase+3, 0x16); //пишем код команду в регистр Host Control Register _outp(SMBusBase+2, 0x4c); WORD data=0; BYTE status = 0; _asm{ xor cx,cx Wait2: mov edx, SMBusBase in al,dx mov status, al test al,ERR_MASK ; {ошибки устройства} jnz EndDataTransfer test al,2 ; {Произошло прерывание} jz Wait1 test al,80 ;{данные пришли} jnz DataReady Wait1: loop Wait2 ;jmp EndDataTransfer DataReady: mov edx, SMBusBase out dx,al ;{ Пишем в регистр статуса, что обнуляет его} add dx,5 ;{+5 Регистр данных Date0} in al,dx mov ah, al inc dx ;{+6 Регистр данных Date1} in al, dx mov data,ax EndDataTransfer: } printf("0x%04lX", data); } void ReadBatteryData( int SMBusBase, BYTE Command ) { //попробуем считать данные батареи printf("\nRead battery data. Command - %d. ", Command); //цикл по ячейкам SPD ClearSMBusStatusReg(SMBusBase); //пишем адрес и направление команды в регистр Transmit Slave Address - батарейка 0001 011b и чтение 1 _outp(SMBusBase+4, 0x17); //пишем код команды в регистр команды контроллера SMBus - чтение статуса _outp(SMBusBase+3, Command); //пишем код команду в регистр Host Control Register _outp(SMBusBase+2, 0x4c); WORD data=0; BYTE status = 0; _asm{ xor cx,cx Wait2: mov edx, SMBusBase in al,dx mov status, al test al,ERR_MASK ; {ошибки устройства} jnz EndDataTransfer test al,2 ; {Произошло прерывание} jz Wait1 test al,80 ;{данные пришли} jnz DataReady Wait1: loop Wait2 jmp EndDataTransfer DataReady: mov edx, SMBusBase out dx,al ;{ Пишем в регистр статуса, что обнуляет его} add dx,5 ;{+5 Регистр данных Date0} in al,dx mov ah, al inc dx ;{+6 Регистр данных Date1} in al, dx mov data,ax EndDataTransfer: } if ((status & ERR_MASK) == 0x4) { printf("Battery error\n"); } else { data = data - data%10; data = data/10; printf(" %d\n ", data); } ReadBatteryStatus(SMBusBase); _getch(); } Но он не работает, и почему я пока не понимаю. Если сможешь найти ошибку буду рад) Только он по прежнему требует драйвер ввода-вывода.
drem1lin А что выводит то? У меня пока нет возможности скомилировать сей код. У меня тоже не работало пока не разобрался наконец с правильным приемом (сколько человек столько и методов). Пришлось опыты проводить. Если интересно, то вот такие опытные данные у меня получились: 1. Если устройства с требуемым адресом на шине I2C не существует, то статус в цикле опроса принимает такие значения: 0000.0001 = busy ... 0000.0101 = busy + deverr ... 0000.0110 = deverr + int <- более не изменяется ... 2. Если устройство существует (напр. 0x50 - планка памяти), то - такие значения: 0000.0001 = busy ... 0000.0000 (0000.0011) = бывает но редко, надо учитывать ... 0000.0010 = int <- более не изменяется ... Ну и вывод, что однозначно можно сказать об "окончательном" завершении транзакции, если BUSY уже нет и INT уже наступило. А бит 7 я не учитываю, уже выше писал про него, и кроме того, в спецификации ICH что-то про блочную передачу написано, по его поводу, а у нас она простая. Да еще, к тебе вопрос, а откуда у тебя знания что в eeprom батарейки, по смещению 0x16 находиться статус батарейки. Где можно взять структуру всей eeprom для батарейки. Скоро уже тоже понадобиться. VaStaNi Я рад что у тебя все работает, но вот оценить и запустить *.exe не горю желанием. Вот если бы исходниками поделился, ну той частью что всех здесь интересует. И раз ты так хорошо разбираешься в этом деле, ну подскажи что мне сделать, чтобы в "чистой" системе (или под DOS) в конфигурационном пространстве PCI, с мостом ICH8M, появилось таки устройство с координатами B00-D1F-F03 (B0-D31-F3).
У меня устанавливается флаг dev_err это точно, остальные не знаю. Если надо завтра документацию по батарейке выложу. Устройство должно существовать, адрес батарейки я взял из спецификации SMBus 2.0
ну в принципе да, данные то по одному проводу транслируются да еще в обоих направлениях + занятие шины, коллизии... Собственно там, я хотел акцентировать внимание на понимание, представление о временной диаграмме работы шины, ЧТО ОЧЕНЬ важно, т.к. отсюда растут ноги ожиданий, паузы и их длительность, задержки и т.д. ВЫДЕРЖИВАНИЕ ПРОГРАММИСТОМ ВРЕМЕННЫХ ДИАГРАММ ДЛЯ МЕДЛЕННЫХ УСТРОЙСТВ и шин обмена очень важна и является основной причиной неудач, ошибок, непонимания почему так неправильно работает....... Кстати порылся в своих хламовниках, вот еще полезное чтиво, кто не ленив и пытлив рекомендую несколькими штрихами дополнить свой кругозор так сказать тут есть несколько ценных крупиц на мой взгляд: http://intpc.ru/interface/155-sravnenie-shin-i2c-access.bus-i-smbus.html http://intpc.ru/interface/154-shina-smbus.html http://www.life-prog.ru/view_periferiynoe_ustroystvo.php?id=1&page=1 http://intpc.ru/interface/154-shina-smbus.html http://www.gaw.ru/html.cgi/txt/interface/iic/index.htm http://cxem.net/comp/comp56.php лучше передать, нежели НЕдодать! ))))) drem1lin вообще язык Це и его разновидности я НЕ использую, не говоря уже что не люблю и "НЕ думаю на нем". Но понять то другое можно, если очень нужно... ) Сражу скажу, что код написан жестко и не видообразно с самого начала! А ведь винда тоже имеет свои правила хорошего тона! Для ожиданий правило хорошего тона гласит - использую неблокирующие вещи, например Sleep(N) в цикле опроса и т.д. Зачем же делать LOOP СХ раз опираясь только на такты процессора? Типично неправильно. А если код будет запускаться на разных процессорах по быстродействию? Тогда как, тогда что на одной машине работает, а на другой - догадайся сам что.... придется вертаться к даденным мной исходнику, так вот там в досе аналогом этого слипа является следующий кусочек Код (Text): pusha xor cx, cx mov dx, 1000 mov ah, 0x86 int 0x15 popa и он ГАРАНТИРУЕТ независимость от процессора... подробности курим int 0x15 доку. Далее. Куда ты, извини поперся уже читать НЕ настроив всего, что положено? Ну ты пусть спешишь победить сабж, пусть даже ленишься или упрямишься, но ты хоть внимательно ПЕРЕСЧИТАЙ КОЛИЧЕСТВО OUTов!!!!!! перед тем как IN делать! Ведь это и есть настройка, подготовка, отдача приказов железяке или комплексу взаимосвязанных железяк, что ИМ НАДО ДЕЛАТЬ и соответсвтенно, что ты от них хочешь получить. А ты типа дождался первой готовности и бегом ать-два!, подавай мне мои любимые блинчики, да побыстрее, некогда мне дескать еще чего то ждать да проверять....хочу и точка! ай,ай,ай! А я и вправду прочитал твои слова выше , что типа неразглядел. Получается ты еще и не начинал смотреть или только вот теперь, похоже и начал, тока всмотреться забыл или неуспел. Я ведь незря говорил думал я, что брильянт стоит того, чтобы посидеть, снять с него шелуху мнимой сложности понимания ассемблера в плане эффективной игры с регистрами... и увидеть, что это уже универсальная, комплексная, вылизанная процедура боевого применения, особенно если не полениться и посмотреть и выше и ниже ее, как и где она вызывается. методы, особенно правильности, они одни и выше о их критериях уже сказано. Имхо. если побайтная вылизалась, то блочная - как два пальца... собственно байт команды другой и блочный IN/OUT юзается... собсссвенно я от него ушел нафига тут некоя блочная скорость? Выигрыш с этой черепахи sSMBus - пшик, а универсальность доступа в пространство теряешь... ноута у меня нет и не было, но я бы начал с хакерских логических методов, снятия дампов с устройств их анализа, затем что и когда и как меняется, например батарея 100% - сфоткал, села на 50% сфоткал, затем сел сличил - выводы, анализ, план действий и по новой, глядишь прояснится явное, может и дока какая под выводы и оффсеты ляжет, вот и успех тогда намечается... ты ясней выражайся, я вот скока поэму пишу тут время трачу, как для людей. Где твоя ясность? Ты свои посты видел, читал? Себя со стороны пробовал почитать, понять? ) Туманно. Обычно на такие посты вообще многие не обращают внимания... подумай над этим. я пишу Код (Text): mov ax, 0xB103 ;найти mov ecx, 0x0C0500 ;класс SMBus устройства mov si, 0 int 0x1A а потом Код (Text): mov di, 0x20 ;номер читаемого регистра mov ax, 0xB109 ;читать WORD значение int 0x1A and cx, 0xFFFE mov dx, cx mov [BaseSMBus], dx прокоментируй, как ты это понимаешь и что получаешь у себя + как согласно твоей доке на SB700 изменится (нужно поменять) занчение 0x20? Все на сегодня, упарился. Никого не хотел учить или обидеть токма советы и рекомендации + имхо, так что без обид. Все по делу и существу, ну разве что в свое манере ) Всем успехов!
Да про слип я знаю просто все регистры заново восстанавливать приходится, так как основная часть кода в ассемблерных вставках. Я не понял какого OUT не хватает. 1. Очистка статусного регистра контроллера SMBus 2. Запись адреса устройства и направления передачи данных 3. Запись кода команды в регистр команды контроллера 4. Запись старта и кода команды в регистр Host Control Register Процедуру изучу еще раз
Дока по батарейке: Да что же это такое, не прикрепляется файл. Дока - Smart Battery Data Specification
VaStaNi Ты вот результат своей работы предлагаешь заценить, выложил exe-ник, а я говорю что лучше бы выложил исходник или на крайний случай его часть. Прога твоя виндовая, в ней всякие окошечки есть, диалоги, контролы, процедура обработки сообщений окна и прочее наверное есть. Так вот, это все можешь не показывать, нам чужего не надо. А вот функции работы с железом была бы очень кстати. Ты вот тут о какой-то подготовке говоришь, о взаимосвязанных железка, так покажи на своем примере как правильно это сделать. Кстати, я тоже считаю что у drem1lin OUT'ов достаточно. Это касается только моста Intel ICH8M. Проблема вот какая. Под виндой, в моем коде и например, в Evereste, находится устройство (по адресу BUS = 0, DEVICE = 31, FUNC = 3 согластно спецификации) с классом 0x0C0500 (SMBus Controller), читается базовый адрес (регистр 0x08 или offset 0x20) = 0x00000401 (видно что это адрес в пространстве I/O). И сообственно все работает. А вот под DOS, при перечислении устройств, по адресу BUS = 0, DEVICE = 31, FUNC = 3 ничего нет. И вообще нет устройства с классом 0x0C0500 (SMBus Controller). BIOS его не включила или даже наоборот, выключила. А мне оно нужно. drem1lin Про батарейку нашел это sbworkshop.com/sbdat110.pdf. Я так полагаю ты этим же пользовался? Добрался я наконец до батареки. Проблемы вылезли и здесь. При перечислении устройст на шине I2C, отвечают какие-то модули, в том числе и планки памяти (SPD) c адресами 0x50, 0x51. А вот то что относится к батарее не отвечает. Это модули с адресами 0x09 (0001 001) - Smart Battery Charger, 0x0A (0001 010) - Smart Battery System Manager, 0x0B (0001 011) - Smart Battery. Они молчат. При чтении по этим адресам, всегда статус DEV_ERR. А как у тебя?
Именно этим У меня я проверил в статус регистре все время 44h. То есть DEV_ERR и бит совместного доступа. Выложи всой код посмотреть для сравнения.
drem1lin, звиняй! Вредно мне писать около полуночи да еще сишные нюансы с подчёркиванием и ниже asm, что только и приковало моё внимание. Слона то я и не заметил, OUTы, как бы у тебя есть... и вроде в том порядке..., но буду "бурчать" дальше, уж извини, но правильности нет. Имхо. Я кумекаю так, что ты решил себе жизнь упростить именно в плане листинга C и порчи регистров....., поэтому напарочь выкинул первый WAIT!!! Так? Ты думаешь я такой умный или нефиг мне делать только бы код понасыщенней ожиданиями понапичкать? А я везде кричу, что я частенько прибегаю к дизасму биоса, особенно, когда там есть чтото непонятненькое, интересненькое, секретненькое для нас смертных, от фирмы разработчика... В данном случае это именно так, а еще этот самый нюансный WAIT - есть подтверждение моих постов выше, соответсвенно доков про временную диаграмму этой "супершины", всякие ожидания мастер-слэйв..... Ладно обратимся к первоисточникам, а то Protorus нагло думает, что я жлоб и код в Win приложении както сильно радикально отличается от того, что я уже давно привел и тыкать туда устал. Итак, еще один раунд азбуки по smbusУ, которую я прошел практическим путем звучит так. "...жил да был один из чипсето-интеловских биосов, имел он характерный smbusОвский код, связанный с регистровой парочкой DX внутрях себя, однажды был пойман за енто место по характерным сигнатурно-опкодовым шрамам на своём поганом теле, проанализирован падла кааов был и кто рядом лежал, затем безжалостно вынут наружу для созерцания и глумленЬя. И предстал он пред ясными очами в своём туповатом и туманном виде на суд и оказался он прост, как "два байта обнулить" (с) VaStaNi. )))))))))) Код (Text): ; --------------------------------------------------------------------------- push cx mov dx, 504h inc ch mov al, ch out dx, al out 0EBh, al out 0EBh, al call sub_EAC81 pop ax mov dl, 3 out dx, al out 0EBh, al out 0EBh, al mov dl, 2 mov al, 48h out dx, al out 0EBh, al out 0EBh, al mov cx, 100h loc_EABC0: out 0EBh, al loop loc_EABC0 call sub_EAC81 mov dl, 5 in al, dx out 0EBh, al out 0EBh, al retn ; --------------------------------------------------------------------------- push cx mov dx, 504h inc ch mov al, ch out dx, al out 0EBh, al out 0EBh, al call sub_EAC81 mov dl, 3 pop ax out dx, al out 0EBh, al out 0EBh, al mov dl, 2 mov al, 4Ch out dx, al out 0EBh, al out 0EBh, al mov cx, 1388h loc_EAC2E: out 0EBh, al loop loc_EAC2E call sub_EAC81 mov dl, 6 in al, dx out 0EBh, al out 0EBh, al mov ah, al mov dl, 5 in al, dx out 0EBh, al out 0EBh, al retn ; --------------------------------------------------------------------------- sub_EAC81: mov dx, 500h clc mov cx, 800h loc_EAC88: in al, dx out 0EBh, al out dx, al out 0EBh, al test al, 2 jnz loc_EACA0 and al, 0BFh or al, al jz loc_EACA0 test al, 4 jnz loc_EAC9E loop loc_EAC88 loc_EAC9E: stc retn Ну что drem1lin, так видней, доступней проще для понимания? Вроде да, но ведь они убогие и куцые процедуры, код дублируется, неоптимален, да и вообще перестраховщики блин напичкали архаизмы out 0EBh, al вот они точно нафиг нужны, мое мнение зиждется в данном случае на современные чипы, частоты, шины... Кстати очередность оффсетов +4, 3, 2 и затем 6, 5 у тебя заметил 5, 6! А у меня еще проще IN AX, DX и никаких гвоздей! Стреляет как и положено, т.к. команда то соответствующая WORD, значит готовность получим по пришествии 2го байта, следовательно можно читать словим, но уже не с шины а из накопительного регистра южника... это почему? Где это написано, что они портятся? Разве только EAX... Впрочем не проверял детально... И потом прямо в ассемблере пишешь: Код (Text): push 10 call Sleep = Sleep(10) Да, вот еще что меня в недоуменье вводит, так это твои засылки 17h, 16h.... уверен? Я не анализировал и не проверял, но кажется..... Ладно, все бегу. Может позже допишу что еще хотел.
Protorus как тут понять какой программой ты это определил? Мой ДОС код что то видит у тебя? Речь я понимаю об интеле? Я не телепат, а ты явно и точно не указываешь, код, дамп его не приводишь. Заначит не факт, а просто личная ошибка где то там... в строке номер 13. drem1lin так, пересмотрел я эту вашу смарт батери. Значится ты читаешь (0x17) по адресу 0xB и ожидаешь получения ее статуса согласно доке находящуюся по смещению 0x16, я так понял. Вопрос. Если предположить, что SpeenFan честно и правильно сканирует все устройства на SMBus то ВООБЩЕ ЭТИ АДРЕСА имеются у тебя в перечне??? Ты не отреагировал на мои закидоны по поводу тестовых прог. Непонятно теперь, что ты юзал, как ты юзал, что видел, кто что НЕ видел... Проигнорировано? Или ты то видел, а мы тут нафиг, нафиг? Нам жежжжж тоже интересна правда про смарты еНти, раз уж пошла такая пьянка... abcd008 доку покажи!? Факты PLZ! А то похоже ты путаешь батарейку кмоса и аккумуляторную батарею ноутбука! drem1lin возникла хитрющая мысль, по поводу того, что бытьможет твой биос что то показывает по аакуму(уровень заряда)??? Если это так и чипсет интел и биос AWARD, то мог бы успеха ради этого вопроса попытаться "понюхать как там енто устроено" ) Но это не бегом конечно и вполне может ничем не увенчаться. Вообщем ширше инфы для мозгования! Пока не надоело, однако. )
Cmos работает не через клаву и не EC, а через порты 70h/71h А про smbus на EC почитай в ACPI доках и на сайте smbus.org(если не ошибся) немного есть. например в чипсете nForce2 вообще два smbus контроллера в одном мосту.
drem1lin Вот-тут выложил пару своих процедур, они на асме и для ядра (или DOSa) http://rghost.ru/2530114 VaStaNi Нашел как включить SMB под DOS. Вот тут пример есть. http://www.xakep.ru/post/47276/default.asp Я в общем-то все так и делал. Но ты прав, это я лоханулся немного. Почему-то, на чипсете intel не включилась линия A20, что-бы развернулось адресное пространство. А так как регистр FD (Function Disable Register) находится в адресном пространстве памяти, а не в пространстве ввода-вывода, как например, у drem1lin в коде, то записывал не в него, а в совершенно другое место. Век живи ... abcd008 Спасибо, теперь задумаюсь. Или может ты расскажешь что это за зверь такой и счем его едят. И вероятно ты прав, т.к. на шине, которую я мучаю, устройств с батареечными адресами не наблюдается. Оффтопик Вот тут есть инресная прога для работы с батареей http://www.avalon.co.ua/be2works/ Кто-нибудь пробывал?
Protorus - благодарю за качественный, профессиональный материал а ассемблерном исполнении! это прога не та. Это технологическая прога для подсоединения внутреннего контроллера аккума к некоторым битам порта LPT. Временная диаграмма SMBus раскручивается этой прогой программным образом в строгом соответствии всех WAIT и т.д. т.е. протокола обмена Master-Slave для I2C. К самой внутренней шине SMBus не имеет никакого отношения.