|
AT91SAM7X I2C, Просто хотел поделиться... |
|
|
|
Jun 19 2008, 10:10
|
Участник

Группа: Участник
Сообщений: 63
Регистрация: 21-09-07
Из: СССР
Пользователь №: 30 719

|
Много раз читал тут, что у людей аппаратный и-квадрат в этом камне не работает. Видел софтовые реализации. Однажды я наткнулся на пример от атмела и сделал свою реализацию. Работает уже год без проблем. Сначала запуск железа: Код AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,(1<<AT91C_ID_TWI)); *AT91C_TWI_CWGR=0x033C3C; Ну ессно и ножки включить, тут думаю каждый справится. Далее собсна чтение: Код void ReadI2C(char *s,unsigned count,char dev,word iaddr) { unsigned i,stt,j; if (count==0) return; *AT91C_TWI_CWGR=0x030F0F; *AT91C_TWI_CR=AT91C_TWI_MSEN; stt=*AT91C_TWI_SR; while (!(stt&AT91C_TWI_TXCOMP)) {stt=*AT91C_TWI_SR;} if (dev==0xD0) i=AT91C_TWI_IADRSZ_1_BYTE; else i=AT91C_TWI_IADRSZ_2_BYTE; *AT91C_TWI_IADR=iaddr; *AT91C_TWI_MMR=(dev<<15)|i|AT91C_TWI_MREAD; if (count==1) { *AT91C_TWI_CR=AT91C_TWI_START|AT91C_TWI_STOP; stt=*AT91C_TWI_SR; while (!(stt&AT91C_TWI_TXCOMP)) {stt=*AT91C_TWI_SR;} s[0]=*AT91C_TWI_RHR; *AT91C_TWI_CR=AT91C_TWI_MSDIS; return; } else *AT91C_TWI_CR=AT91C_TWI_START; s[0]=*AT91C_TWI_RHR; for (i=0; i<count; i++) { stt=*AT91C_TWI_SR; j=10000; while (!(stt&AT91C_TWI_RXRDY)&&--j) {stt=*AT91C_TWI_SR;} if (!j) {error|=NOEEP; return;} s[i]=*AT91C_TWI_RHR; } *AT91C_TWI_CR=AT91C_TWI_STOP; stt=*AT91C_TWI_SR; while (!(stt&AT91C_TWI_TXCOMP)) {stt=*AT91C_TWI_SR;} *AT91C_TWI_CR=AT91C_TWI_MSDIS; } И запись: Код void WriteI2C(char *s,unsigned count,char dev,word iaddr) { unsigned i,stt,j; if (count==0) return; switch (dev) { case 0xEE: i=AT91C_TWI_IADRSZ_NO; *AT91C_TWI_CWGR=0x033C3C; break; case 0xD0: i=AT91C_TWI_IADRSZ_1_BYTE; *AT91C_TWI_CWGR=0x030F0F; break; case 0xA6: case 0xA0: i=AT91C_TWI_IADRSZ_2_BYTE; *AT91C_TWI_CWGR=0x030F0F; break; } *AT91C_TWI_CR=AT91C_TWI_MSEN; stt=*AT91C_TWI_SR; j=20000; while (!(stt&AT91C_TWI_TXCOMP)&&--j) {stt=*AT91C_TWI_SR;} *AT91C_TWI_MMR=(dev<<15)|i; *AT91C_TWI_IADR=iaddr; if (count==1) { *AT91C_TWI_CR=AT91C_TWI_START|AT91C_TWI_STOP; *AT91C_TWI_THR=s[0]; stt=*AT91C_TWI_SR; j=20000; while (!(stt&AT91C_TWI_TXCOMP)&&--j) {stt=*AT91C_TWI_SR;} *AT91C_TWI_CR=AT91C_TWI_MSDIS; return; } else *AT91C_TWI_CR=AT91C_TWI_START; for (i=0; i<count; i++) { *AT91C_TWI_THR=s[i]; stt=*AT91C_TWI_SR; j=20000; while (!(stt&AT91C_TWI_TXRDY)&&--j) {stt=*AT91C_TWI_SR;} if (!j) { error|=NOEEP; return;} } *AT91C_TWI_CR=AT91C_TWI_STOP; stt=*AT91C_TWI_SR; j=20000; while (!(stt&AT91C_TWI_TXCOMP)&&--j) {stt=*AT91C_TWI_SR;} *AT91C_TWI_CR=AT91C_TWI_MSDIS; } В примере записи происходит переключение скоростей под разную переферию. Используются часы, два епрома и пик. Все работает!
--------------------
Сомневаюсь, и вам советую!
|
|
|
|
|
 |
Ответов
|
Jun 20 2008, 20:57
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(mungo @ Jun 19 2008, 14:10)  Много раз читал тут, что у людей аппаратный и-квадрат в этом камне не работает. Видел софтовые реализации. Однажды я наткнулся на пример от атмела и сделал свою реализацию. Работает уже год без проблем. Он как бы работает но не совсем, самая главная проблемма в работе i2c на sam7 заключается в том, что i2c на sam7 работает практически в синхронном режиме, те рассчитывать на то что slave может задержать транзакцию на неопределенное время не приходиться.... то есть слейв просто должен начинать отвечать практически мгновенно... для железок типа EEPROM это всегда выполняется...
|
|
|
|
|
Jun 22 2008, 16:54
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Jun 21 2008, 02:52)  В этом есть своя прелесть, меньше шансов подвесить систему слейвом. Да и нечего слейву тормозить транзакцию. Слейв должен укладываться в клок мастера, иначе - надо снижать скорость. Цитата(defunct @ Jun 21 2008, 03:06)  На мой взгляд это не проблема, и даже не фича, а то как должно быть. Не успевает слейв, значит NACK и в сад такой слейв, и освободить шину для тех кто успевает. Цитата(aaarrr @ Jun 21 2008, 03:20)  Есть слейвы, которые принципиально всегда держат SCL при обращении к некоторым регистрам (TVP5150, например) - так что, в сад их всех? Цитата(defunct @ Jun 21 2008, 03:28)  там же есть I2C Timing Requirements ставить подобающую скорость. (для TVPS5150 - 15kHz для тех регистров которые тормозят). Цитата(aaarrr @ Jun 21 2008, 03:40)  Согласитесь, что нормальный I2C-контроллер не должен вынуждать пользователя заниматься такими извращениями - ронять скорость обмена в 30 раз. ИМХО: - I2C статическая шина просто по определению - попросы подвешивания шины должны решаться механизмами таймаутов как на стороне мастера так и на стороне слейва(особенно при софтовой реализации слейва) - исходя из статической природы I2C обязателен мониторинг SCL мастером - снижение скорости шины(для устройств которы не готовы отвечать мгновенно) только уменьшит пропускную способность всей шины ИМХО, конкретный пример: - слейв - микроконтроллер - запрос от мастера может иметь разную длинну - при получении запроса от мастера слейв должен чего-нить сделать(банально скопировать запрошенные данные в буфер обмена) - время готовности слейва зависит от типа(длинны)/сущности запроса Цитата Собсно программный I2C (надежный как бревно) разве чем-то отличается? Тоже синхронный. Или кто-то мониторит SCL? По стандарту, мониторить SCL есть прямая обязанность мастера.
|
|
|
|
|
Jun 29 2008, 01:43
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(singlskv @ Jun 22 2008, 19:54)  ИМХО: - I2C статическая шина просто по определению - вопросы подвешивания шины должны решаться механизмами таймаутов как на стороне мастера так и на стороне слейва(особенно при софтовой реализации слейва) - исходя из статической природы I2C обязателен мониторинг SCL мастером - снижение скорости шины(для устройств которы не готовы отвечать мгновенно) только уменьшит Наблюдал однако как LPC с его абсолютно правильным I2C модулем подвисал из-за того, что слейв передерживал SCL. И приходилось переинициализировать модуль. Поэтому тормозные слейвы лучше сразу в сад. Природа обмена IMHO должна быть синхронной, чтобы мастер с множеством других девайсов на шине никак не зависел от конкретного одного слейва. И я очень рад, что в SAM синхронный модуль. Цитата ИМХО, конкретный пример: - слейв - микроконтроллер - запрос от мастера может иметь разную длинну - при получении запроса от мастера слейв должен чего-нить сделать(банально скопировать запрошенные данные в буфер обмена) - время готовности слейва зависит от типа(длинны)/сущности запроса Пример не убедительный. Предложу свой протокол, который решает проблемы задержек при обмене МК-МК. типы транзакций: 1. Команда (от мастера к слейву) 2. Ответ (от слейва к мастеру) 3. Индикатор (от слейва к мастеру) 4. Подтверждение индикатора (от мастера к слейву) по формату то же что и "1". Теперь как это работает. A. каждый пакет начинается байтом длины (что накладывает ограничение на длину пакета - 255) B. от мастера к слейву - никаких проблем, мастер просто передает блок данных, слейв просто принимает и складывает по прерыванию каждый байт данных. (уж положить байт в буфер не бог весть какая задача, если программа сделана без delay_ms в обработчиках прерываний, то ACK слейв сформировать без задержек успеет). C. По приему всего пакета слейв начинает его разбор. Столько веремени сколько нужно. Мастер в это время волен общаться с другим слейвом. D. мастер забирает ответ слейва или индикатор (от слейва к мастеру). - Если у слейва есть что отправить (команда выполнена есть подготовленный к отправке "ответ", или есть запрос к мастеру "индикатор"), то первым байтом слейв передает длину блока. Мастер инициализирует счетчик ожидаемых байт и продолжает прием, зная когда надо отправить NACK на последный байт. - Если у слейва ответ не подготовлен, то он сразу шлет 0 без разбора, мастер ставит NACK, вытаскивает еще один байт данных, завершает обмен. И переходит к другому слейву. Вот и все, все синхронно и никаких задержек. PS: в моей системе мастер выполняет роль маршрутизатора (принимает данные с одного быстрого канала и шлет (направляет пакеты) на несколько до 64х медленных каналов, которые обслуживаются I2C слейвами mega'ми). Мастер раздает команды всем слейвам, потом забирает ответы.
|
|
|
|
|
Sep 10 2009, 17:40
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 11-10-06
Пользователь №: 21 214

|
Цитата Если придерживаться стандарта, то в софтверной реализации надо реализовывать мониторинг SCL
В девайсе с TVP5150 я так и сделал. Я так понял, исходя из беседы, что аппаратный TWI в AT91SAMxxx глючноват, тем более применимо к TVP5150/SAA71xx. А я как раз собираюсь подключить TVP5150 к SAM9260. Рано или поздно я его конечно запущу, но чтобы не наступать на грабли, не дадите ли ссылку на приличный софтовый I2C и общих рекомендаций по стыкованию?
|
|
|
|
Сообщений в этой теме
mungo AT91SAM7X I2C Jun 19 2008, 10:10 aaarrr Без прерываний, без контроля ошибок...
Я не хочу ... Jun 19 2008, 12:16 mungo На вкус и цвет...
Суть: ЭТО действительно работает... Jun 20 2008, 09:59 xelax Цитата(mungo @ Jun 20 2008, 13:59) На вку... Jun 20 2008, 10:14 aaarrr Цитата(mungo @ Jun 20 2008, 13:59) А насч... Jun 20 2008, 10:15  aaarrr Цитата(defunct @ Jun 21 2008, 02:52) Собс... Jun 20 2008, 22:57   defunct Цитата(aaarrr @ Jun 21 2008, 01:57) Почем... Jun 20 2008, 23:06    aaarrr Цитата(defunct @ Jun 21 2008, 03:06) Каки... Jun 20 2008, 23:20     defunct Цитата(aaarrr @ Jun 21 2008, 02:10) SAA71... Jun 20 2008, 23:21      aaarrr Действительно выдает. Jun 20 2008, 23:21     defunct Цитата(aaarrr @ Jun 21 2008, 02:20) Есть ... Jun 20 2008, 23:28      aaarrr Цитата(defunct @ Jun 21 2008, 03:28) там ... Jun 20 2008, 23:40       defunct Цитата(aaarrr @ Jun 21 2008, 02:40) Нет, ... Jun 20 2008, 23:44        aaarrr Цитата(defunct @ Jun 21 2008, 03:44) Так ... Jun 21 2008, 00:16         defunct Цитата(aaarrr @ Jun 21 2008, 03:16) На ви... Jun 21 2008, 00:23          aaarrr Цитата(defunct @ Jun 21 2008, 04:23) Очен... Jun 21 2008, 00:36           defunct Цитата(aaarrr @ Jun 21 2008, 03:36) Фронт... Jun 21 2008, 01:13 aaarrr Детально я эту форму не изучал - для этого нужно з... Jun 21 2008, 10:33
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|