реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> AT91SAM7S128: снова TWI, теперь глюк в прерывании
vet
сообщение Mar 16 2006, 15:33
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



По непонятной причине портится последний байт при чтении данных из устройства (I2C FRAM).

Процедура чтения, запускающая обмен по прерываниям:
Код
  //buf - буфер чтения, len - сколько байт читать

  if (len>1) {
    *AT91C_TWI_CR = AT91C_TWI_START;
    *AT91C_TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK | AT91C_TWI_OVRE;
  }
  else {
    *AT91C_TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
    *AT91C_TWI_IER = AT91C_TWI_TXCOMP;
  }
  WAIT(semaphore, timeout); //ждать окончания приёма


Обработчик прерывания TWI; показано только чтение, обработка ошибок убрана:
Код
void TWI_ISRHandler() {
  unsigned int status;

  status = *AT91C_TWI_SR;    //маска событий
  status &= *AT91C_TWI_IMR;

  *AT91C_AIC_IVR   = 0;                /* Debug variant of vector read (protect mode is used)  */
  *AT91C_AIC_ICCR  = 1<<AT91C_ID_TWI;  /* Clear TWI interrupt                                  */

  if (status&AT91C_TWI_TXCOMP) { //STOP передан, дождаться последнего байта
    *AT91C_TWI_IDR = 0xFFFFFFFF;
    *AT91C_TWI_IER = AT91C_TWI_RXRDY;
  }

  if (status&AT91C_TWI_RXRDY) {  //принят байт
    char n = *AT91C_TWI_RHR;    //очистить приемник, снять RXRDY
    *buf++ = n; //записать принятый байт в буфер
    if (len>1) {
      if (--len==1) {     //принят предпоследний байт - послать STOP и принять последний байт
        *AT91C_TWI_IDR = 0xFFFFFFFF;
        *AT91C_TWI_CR = AT91C_TWI_STOP;
        *AT91C_TWI_IER = AT91C_TWI_TXCOMP;
      }
    }
    else {                       //принят последний байт
      *AT91C_TWI_IDR = 0xFFFFFFFF;
      SIGNAL(semaphore);    //завершить чтение, вернуть управление вызывающей процедуре
    }
  }

  *AT91C_AIC_EOICR = 0;                /* Signal end of interrupt                              */
}


Если читаю из уст-ва один байт, ошибок нет. Если несколько - последний байт считывается неверно. Посоветуйте, как с этим бороться?


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
zhek
сообщение Apr 12 2006, 07:45
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



Вот и я до TWI добрался. Два дня парюсь, уже думаю сделать его программно, ножками дергать. Вопрос такой: удалось заставить его работать? У меня по коду (выше) есть предположения, но он, наверное, изменился?

Вообще толково придумано, что надо каждый байт отслеживать и суметь твй вовремя заткнуть, а то будет колбасить до посинения. И еще статус читать нельзя, а то "may be lost".
Go to the top of the page
 
+Quote Post
zhek
сообщение Apr 12 2006, 07:56
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 29-12-05
Из: Екатеринбург
Пользователь №: 12 692



И, похоже, прерывания не по всякому флагу можно делать

Сообщение отредактировал zhek - Apr 12 2006, 07:58
Go to the top of the page
 
+Quote Post
vet
сообщение Apr 12 2006, 07:58
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



По теме - обошёлся приёмом лишнего байта с последующим его игнорированием. В остальном код не изменился.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 12 2006, 09:29
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



А зачем на предпоследнем байте прерывания приема запрещать?
Похоже, тут ваш байт и теряется.
Go to the top of the page
 
+Quote Post
vet
сообщение Apr 12 2006, 09:38
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Он принимается после посылки STOP и последующего обнаружения AT91C_TWI_TXCOMP; но принимается неправильный байт.
Есть мнение, что при приёме нескльких байт с устройства надо поменять местами эти две стадии, но проверить сейчас не могу - проект закончен, и пока что я к ARM не возвращался.

Сообщение отредактировал vet - Apr 12 2006, 09:49


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 12 2006, 09:51
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(vet @ Apr 12 2006, 13:38) *
Он принимается после посылки STOP и последующего обнаружения AT91C_TWI_TXCOMP; но принимается неправильный байт.
Есть мнение, что при приёме нескльких байт с устройства надо поменять местами эти две стадии, но проверить сейчас не могу - проект закончен, и пока что я к ARM не возвращался.


Правильное мнение, но и с прерываниями так обращаться все же не стоит.
Одна из возможных причин потери байта описана в errat'е.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 09:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01397 секунд с 7
ELECTRONIX ©2004-2016