Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Зависает TWI в SAM7
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
jhoo
Использую TWI для работы с еепром и ртц. Все работает как положено. Параллельно работает тамер 0, в обработчике прерывания которого выполняю некоторую работу. Вот что заметил - если прерывание таймера длится относительно долго (точный предел не знаю, у меня около 80мкс), то после выхода из него и возврата к продолжению работы с еепром TWI зависает на проверке статуса готовности принятых данных. Если длительность прерывания таймера маленькая, то все нормально.
Программа выглядит примерно так:

Код
main()
{
//.......
    while (1)
    {
         EEPR_ReadData(...);
    }

}

void Timer0IRQ(void)
{
// что-то делаю (~80 мкс)
}

int AT91F_TWI_ReadData(LPVOID Data, int Size)
{
    int Error=0;
    int Status,Count=0;
    AT91PS_TWI pTwi = AT91C_BASE_TWI;
    BYTE *pData = (BYTE*)Data;

    pTwi->TWI_MMR |= AT91C_TWI_MREAD;

    {
         pTwi->TWI_CR = AT91C_TWI_START;
         for(Count=0; Count<Size; Count++)
         {
            if (Count == (Size - 1))    pTwi->TWI_CR = AT91C_TWI_STOP;

            Status = pTwi->TWI_SR;
            while (!(Status & AT91C_TWI_RXRDY))
            {
                Status = pTwi->TWI_SR;       //  <---------- В этом цикле происходит зависание
            }
            *pData++ = pTwi->TWI_RHR;
        }
    }

    return 0;
}


Т.е. получается что TWI не любит когда его прерывают на длительное время? Как с этим бороться, ведь теоретически прерывания могут длиться любое время.
MemoryTest
Я Делать так! не на саме7 а на рм9200, думаю тут таже бага. У Вас происходит переполнение твй.

Это при чтении

//do read
try_again:

length = 9;
not_success=0;
if(try_count==10) goto cleanUp; //stop our try's

/* Set the TWI Master Mode Register */
twi->TWI_MMR = ((RTC8564_ADDRESS << 16) | AT91C_TWI_IADRSZ_1_BYTE | AT91C_TWI_MREAD);


// Set TWI Internal Address Register
twi->TWI_IADR = 0x0;

// Start transfer
twi->TWI_CR = AT91C_TWI_START;

status = twi->TWI_SR;



for(ii=0;ii<length;ii++){
tmp=0;

// Wait RHR Holding register is full
while ((tmp & AT91C_TWI_RXRDY)==0)
{
tmp = twi->TWI_SR;
buffer_misc[ii]=tmp;
if(tmp&AT91C_TWI_OVRE) {not_success=1; break;}
}

// Read byte
buffer[ii] = twi->TWI_RHR;

}

twi->TWI_CR = AT91C_TWI_STOP;

status = twi->TWI_SR;

// Wait transfer is finished
while (!(twi->TWI_SR & AT91C_TWI_TXCOMP));
// Read last byte
buffer[ii] = twi->TWI_RHR;

//inc my try count
try_count++;
if(not_success) goto try_again;

cleanUp:




Это при записи

while ((tmp & AT91C_TWI_TXRDY)==0)
{
tmp = twi->TWI_SR;
buffer_misc[ii]=tmp;
if(tmp&AT91C_TWI_UNRE) {not_success=1; break;}
}
jhoo
Цитата
MemoryTest

Действительно, проблема была в overrun error. Нужно было отлавливать это событие.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.