jhoo 0 22 декабря, 2005 Опубликовано 22 декабря, 2005 · Жалоба Использую 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 0 22 декабря, 2005 Опубликовано 22 декабря, 2005 · Жалоба Я Делать так! не на саме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 0 22 декабря, 2005 Опубликовано 22 декабря, 2005 · Жалоба MemoryTest Действительно, проблема была в overrun error. Нужно было отлавливать это событие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться