Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATtiny2313 I2C Slave Прием, как поймать стоп
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Мусатов Константин
Суть в том, что мастер (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 или продолжение? Или я туплю и есть способ элегантнее?
dimka76
Цитата(Мусатов Константин @ Jun 20 2009, 03:32) *
Но в 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

Вот его и тестируйте.
manul78
... Возьми стандартную "библиотеку" из 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-ов, код программы должен работать, а не сидеть в ожидниях. Практически, я спрашиваю о чужом опыте, как лучше?
Sanya_kv
В TWI(I2C) приемник при принятии очередного байта обязан передавать AСK или NAСK, обычно делается так, в начале передатчик указывает сколько данных он хочет передать (1-й байт), далее сами данные. Приемник принимая данные выставляет АСК и только при принятии последнего байта NACK. У меня реализовано так и все работает без проблем.


А что разве в ATTiny2313 есть I2C (TWI)?
Мусатов Константин
Цитата
А что разве в 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;
Sanya_kv
Цитата
Разве это корректно? Если нормально принимаешь, то всегда надо ACK выставлять, а как мастер решит что хватит передавать, то он перестает и выставляется stop condition. А то получается, что сигнализируем, что последний байт мы не приняли нормально. Конечно это останавливает передачу, но сама логика как-то нарушена. Или я не прав?

Брал из документации по железу, Atmel сам это рекомендовал. Полагаю условие стоп тоже можно использовать.
По крайне мере логика TWI этому не противоречит.
ReAl
Цитата(Мусатов Константин @ Jun 20 2009, 18:59) *
Разве это корректно? Если нормально принимаешь, то всегда надо 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 от ведущего следует рассматривать как "давай ещё".
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, то это уже состояние ошибки, ведомый с мастером не синхронизованы по передаваемым данным.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.