Перейти к содержанию
    

ATtiny2313 I2C Slave Прием, как поймать стоп

Суть в том, что мастер (ATMega1280) шлет строку для вывода разной длины. Конец строки знаменуется концом передачи - stop condition. Но в ATTiny2313, как я понял, нет прерывания при достижении конца приема. В качестве образца кода драйвера использован классиеский пример AVR312. Может в код

    // ----- Master read data mode ------
    // Set USI to sample data from master. Next USI_SLAVE_GET_DATA_AND_SEND_ACK.
    case USI_SLAVE_REQUEST_DATA:
      USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
      SET_USI_TO_READ_DATA();
      break;

добавить while с ожиданием будет stop или продолжение? Или я туплю и есть способ элегантнее?

Изменено пользователем Мусатов Константин

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но в ATTiny2313, как я понял, нет прерывания при достижении конца приема.

 

Зато есть флаг

Bit 5 – USIPF: Stop Condition Flag

When Two-wire mode is selected, the USIPF flag is set (one) when a stop condition is

detected. The flag is cleared by writing a one to this bit. Note that this is not an interrupt

flag. This signal is useful when implementing Two-wire bus master arbitration.

 

в регистре USISR

 

Вот его и тестируйте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... Возьми стандартную "библиотеку" из WINAVR называется TWI , слегка подумай над ней ... и все срастется...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зато есть флаг

 

Цитата

Bit 5 – USIPF: Stop Condition Flag

When Two-wire mode is selected, the USIPF flag is set (one) when a stop condition is

detected. The flag is cleared by writing a one to this bit. Note that this is not an interrupt

flag. This signal is useful when implementing Two-wire bus master arbitration.

 

 

в регистре USISR

 

Вот его и тестируйте.

Все верно. Но где его анализировать: в основном цикле прогаммы или внутри прерывания? Я не сторонник подолгу сидеть внутри while-ов, код программы должен работать, а не сидеть в ожидниях. Практически, я спрашиваю о чужом опыте, как лучше?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В TWI(I2C) приемник при принятии очередного байта обязан передавать AСK или NAСK, обычно делается так, в начале передатчик указывает сколько данных он хочет передать (1-й байт), далее сами данные. Приемник принимая данные выставляет АСК и только при принятии последнего байта NACK. У меня реализовано так и все работает без проблем.

 

 

А что разве в ATTiny2313 есть I2C (TWI)?

Изменено пользователем Sanya_kv

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что разве в ATTiny2313 есть I2C (TWI)?

В ней есть USI, котрый может работать в режиме TWI, но обработку протокола I2C надо делать кодом, железного драйвера нет.

 

Приемник принимая данные выставляет АСК и только при принятии последнего байта NACK.

Разве это корректно? Если нормально принимаешь, то всегда надо ACK выставлять, а как мастер решит что хватит передавать, то он перестает и выставляется stop condition. А то получается, что сигнализируем, что последний байт мы не приняли нормально. Конечно это останавливает передачу, но сама логика как-то нарушена. Или я не прав?

 

Господа, корректно ли делать проверку

USISR & (1<<USIPF)

внутри прерывания по переполнению

    case USI_SLAVE_REQUEST_DATA:
      USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
      SET_USI_TO_READ_DATA();
      break;

? Может надо небольшую задержку вставить? Неужели никто корректно stop на ведомом не обрабатывал?

Очень не хочется это переносить в рабочий цикл, там время реакции не определено. Пеедавать длину посылки считаю костылем, который уж если и прилаживать, то в самый последний момент.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если кому интересно, вопрос решился простым дополнением указанного фрагмента из обработчика прерывания по переполнению USI

 

    case USI_SLAVE_REQUEST_DATA:
      USI_TWI_Overflow_State = USI_SLAVE_GET_DATA_AND_SEND_ACK;
      SET_USI_TO_READ_DATA();
      while ( (PIN_USI & (1<<PORT_USI_SCL)) == 0 );   
      while ( (PIN_USI & (1<<PORT_USI_SCL)) )
      {
        if((USISR & (1<<USIPF)) )
        {
//    Собственно выполнить действие по фиксации принятых данных, как завершенного пакета
        }
      }
      //clr( LED );
      break;

Изменено пользователем Мусатов Константин

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разве это корректно? Если нормально принимаешь, то всегда надо ACK выставлять, а как мастер решит что хватит передавать, то он перестает и выставляется stop condition. А то получается, что сигнализируем, что последний байт мы не приняли нормально. Конечно это останавливает передачу, но сама логика как-то нарушена. Или я не прав?

Брал из документации по железу, Atmel сам это рекомендовал. Полагаю условие стоп тоже можно использовать.

По крайне мере логика TWI этому не противоречит.

post-45369-1245655094_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разве это корректно? Если нормально принимаешь, то всегда надо ACK выставлять, а как мастер решит что хватит передавать, то он перестает и выставляется stop condition. А то получается, что сигнализируем, что последний байт мы не приняли нормально. Конечно это останавливает передачу, но сама логика как-то нарушена. Или я не прав?
А Вы почитайте родное филипсовское описание I2C, а не гадайте "логично - не логично":

If a master-receiver is involved in a transfer, it must signal the end of data to the slave-transmitter by not generating an acknowledge on the last byte that was clocked out of the slave. The slave-transmitter must release the data line to allow the master to generate a STOP or repeated START condition.

Логика - после опускания ведущим SCL в конце "9-го" такта, тактирующего бит подтверждения, ведомый уже должен выдать первый бит следующего читаемого байта. Потому как когда SCL поднимется на первый импульс следующего байта - выдавать уже поздно, состояние SDA ведомый не имеет права менять. Ну а если старший бит следующего байта 0 ? Как тогда ведущий сформирует СТОП, если линия данных притянута ведомым к земле?

Вот поэтому ведущий и даёт NAK на следующий байт - как признак окончания передачи.

Т.е. в случае чтения из ведомого бит NAK от ведущего следует рассматривать как "давай ещё".

i2cspec.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сори поспешил с выводами.

Изменено пользователем Sanya_kv

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

If a master-receiver is involved in a transfer, it must signal the end of data to the slave-transmitter by not generating an acknowledge on the last byte that was clocked out of the slave. The slave-transmitter must release the data line to allow the master to generate a STOP or repeated START condition.

Во первых, это несколько не то, о чем я спрашивал. К тому же тут рассматривается не совсем хорошая ситуация - мастер прерывает передачу (то ли память кончилась, то ли протокол нарушен...). Т.е. если идет нормальный обмен, то прерывать никого не надо, каждый выдаст столько байт, сколько предусмотрено протоколом (не I2C, а конкретного устройства).

А Вы почитайте родное филипсовское описание I2C, а не гадайте "логично - не логично":

У протокола I2C есть своя логика. Я ее понимаю так, что когда все нормально, то любая передача подтверждается ACK. NAK используется для сигнализации ошибки, как то после передачи адреса не нашелся такой абонент или после передачи байта что-то стало не так. И в приведенной цитате расписано как надо себя вести в ответ на NAK.

 

Логика - после опускания ведущим SCL в конце "9-го" такта, тактирующего бит подтверждения, ведомый уже должен выдать первый бит следующего читаемого байта

Я рассматриваю не чтение из ведомого, а простую запись в него, т.е. все только в одну сторону от мастера к ведомому. И для этой ситуации произвожу поиск СТОП условия, которое не обрабатывается железно.

Т.е. в случае чтения из ведомого бит NAK от ведущего следует рассматривать как "давай ещё".
Точнее АСК.

Вот поэтому ведущий и даёт NAK на следующий байт - как признак окончания передачи.
Да. Однако логической ошибки нет, если ведомый передатчик уже все передал и такой NAK только подтверждает окончание передачи. Вот если ведомый передатчик имеет в очереди на отправку еще байты, а ему сказали NAK, то это уже состояние ошибки, ведомый с мастером не синхронизованы по передаваемым данным.
Изменено пользователем Мусатов Константин

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...