Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Пробемы с инициализацией SPI и USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Daermon
AT91rm9200 на плате AS9200
Проект IAR 4.41a


Если инициализирую и запускаю по отдельности USART и SPI то все работает...

Если последовательно вызываю инициализацию USART и SPI то одно из двух не работает

Думаю проблеммы с инициализацией AIC/

Все проблемы начинаются после вызова __enable_interrupt();


void DAC::Init()
{
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,16);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, 16);

AT91F_PIOA_CfgPMC();// ðàçðåøàåì êëîêè ÏÈÎ
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,
((unsigned int) AT91C_PA4_NPCS1 ) |
((unsigned int) AT91C_PA1_MOSI ) |
((unsigned int) AT91C_PA2_SPCK ), // Peripheral A
0); // Peripheral B
//AT91F_AIC_CfgPMC(); // ðàçðåøèëè êëîêè. ïîêà âñå.
AT91F_SPI_CfgPMC();
SPI_Configure(AT91C_BASE_SPI, AT91C_SPI_MSTR| // Master Mode
AT91C_SPI_PS_FIXED| // Fixed peripheral
AT91C_SPI_MODFDIS| // Mode Fault Detection disable
AT91C_SPI_PCS1 // Âûáðàí 1 ÷èï
// AT91C_SPI_DLYBCS_
);

AT91F_SPI_CfgCs (1, (unsigned int)(32<<8) | // SPCK Baudrate MCK =MCK/(2* SCBR(=32)), MCK/64 = 0.9 ÌÃö = 1ìêñ
AT91C_SPI_BITS_8 | // 16 áèò
AT91C_SPI_CPOL| // Ïîëÿðíîñòü êëîêà
AT91C_SPI_NCPHA
// AT91C_SPI_DLYBCT // çàäåðæêà ìåæäó ïîñëåäîâàòåëüíûìè äàííûìè
); // Çàäåðæêà ìåæäó CS
//((unsigned int) 0x2 << 00));
AT91F_SPI_Enable(AT91C_BASE_SPI); // Ðàçðåøàåì SPI
AT91F_PDC_Open(AT91C_BASE_PDC_SPI); //PDC îòêðûâàåì
// Êîíôèãóðèðóåì AIC
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SPI,0, 0, (void (*)(void))IRQ_SPI);
AT91C_BASE_AIC->AIC_EOICR = 0 ; /* unstack one level */
AT91C_BASE_AIC->AIC_ICCR = ( 1<<AT91C_ID_SPI );

AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI);

AT91F_SPI_EnableIt(AT91C_BASE_SPI,AT91C_SPI_SPENDTX); //AT91C_US_RXRDY);



}



///*******************************************************************************
void Usart1::Init()
{
for(int i=0;i<100;i++) OutBuf[i] = i+100;
PIO_Init();
AT91F_US1_CfgPMC();// ðàçðåøèëè êëîêè
//AT91F_US_Close(AT91C_BASE_US1); // çàêðûâàåì

//AIC_Init();
AT91F_US_Configure (
AT91C_BASE_US1, // \arg pointer to a USART controller
60000000, // \arg peripheral clock - 60 ÌÃö
AT91C_US_USMODE_NORMAL | // normal mode
AT91C_US_CLKS_CLOCK | // clock is MCK
AT91C_US_CHRL_8_BITS | // 8 databits
AT91C_US_PAR_NONE | // no parity
AT91C_US_NBSTOP_1_BIT | // 1 stopbit
AT91C_US_CHMODE_NORMAL // channel mode - normal
// AT91C_US_CHMODE_LOCAL // channel mode - local
, // \arg mode Register to be programmed
9600 , // \arg baudrate to be programmed
0 ); // \arg timeguard to be programmed

AT91F_US_ResetTx(AT91C_BASE_US1);
AT91F_US_ResetRx(AT91C_BASE_US1);

AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US1,AT91C_AIC_PRIOR_LOWEST, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, (void (*)(void))IRQ1_USART);
AT91C_BASE_AIC->AIC_EOICR = 0 ; /* unstack one level */
AT91C_BASE_AIC->AIC_ICCR = ( 1<<AT91C_ID_US1 );
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US1);

AT91F_US_ReceiveFrame (AT91C_BASE_US1,RxBuffer, Rx_Len, 0,0 );

__enable_interrupt();

Вот на эту команду уже не попадаю
AT91F_US_EnableIt(AT91C_BASE_US1,AT91C_US_ENDRX); //AT91C_US_RXRDY);
}




Может есть какие нить особенности по порядку инициализации AIC?
Dron_Gus
При инициализации желательно очищать все флаги в статус-регистрах.

Похожк что после __enable_interrupt(); Вы улетаете в обработчик прерывания и там и крутитесь, т.к. похоже не снимате бит, вызывающий прерывание.
Daermon
По отдельности то все работает...какие именно биты чистить?
sergik_vrn
Цитата(Daermon @ Dec 28 2007, 16:15) *
По отдельности то все работает...какие именно биты чистить?

правильно ли я понял, что прерывания разрешаются внутри инициализатора UART? если да, тогда причина взаимных глюков очевидна - после разрешения прерываний происходит прерывание SPI (которое, очевидно, разрешается при его инициализации).
Daermon
Пока небудет __enable_interrupt(); прерывания не срабатывают.
sergik_vrn
Цитата(Daermon @ Dec 29 2007, 08:20) *
Пока небудет __enable_interrupt(); прерывания не срабатывают.

не понял, к чему это?
если не вызывать init_spi(), SPI не включится, прерывания по нему происходить не будут, разрешай-не разрешай. если прерывания включаются в init_usart(), то когда его не вызываешь, тоже прерывания не происходят - не разрешены. а когда вызываешь обе процедуры, то условия для зависания создаются.
Daermon
Вот как раз и непонятно почему условия для зависания создаются?
В обработчиках прерывания статус регистры читаю,
на выходе из прерывания ставлю
AT91C_BASE_US1->US_CR = AT91C_US_RSTSTA;
AT91C_BASE_AIC->AIC_EOICR = 0 ;

Поэтому не понятно что может привести к зацикливанию на прерывании
Сергей Борщ
Цитата(Daermon @ Jan 9 2008, 07:53) *
Поэтому не понятно что может привести к зацикливанию на прерывании
Вы разобрались, в каком именно прерывании происходит зацикливание? Или происходит не зацикливание, а сброс или переход в какой-либо из абортов? Статус регистры читаете, а данные из US_RHR вычитываете? Покажите обработчик.
Daermon
Обошел проблему путем исключения прерывания SPI - по опросу статус регистра все работает нормально. Но все же хотел бы разобраться как правильно запустить через прерывания.

Обработчик SPI:
static __arm __irq void IRQ_SPI()
{
AT91C_BASE_AIC->AIC_IVR = 0 ; /* enter interrupt in protected mode */
unsigned int st,st1;
st = (AT91C_BASE_SPI->SPI_SR) ;
st1 = (AT91C_BASE_SPI->SPI_IMR);
st &=st1;
AT91C_BASE_SPI->SPI_IDR = (0xFFFFFFFF);
if( st & AT91C_SPI_SPENDTX)
{

передача следующей посылки

}
AT91F_SPI_EnableIt(AT91C_BASE_SPI,AT91C_SPI_SPENDTX); //AT91C_US_RXRDY);
// ñ÷èòàåì ÷òî ïðåðûâàíèå çàêîí÷åíî
AT91C_BASE_AIC->AIC_EOICR = 0 ;

};

//*************************************************************************
Обработчик USART:

static __arm __irq void IRQ1_USART()
{
unsigned int status;
unsigned int status1;
// char mesag[40];
//----------------------------------
AT91C_BASE_AIC->AIC_IVR = 0 ; /* enter interrupt in protected mode */
//* get Usart status register and active interrupt
status = (AT91C_BASE_US1->US_CSR) ;
status1 = (AT91C_BASE_US1->US_IMR);
status &=status1;
if(AT91F_US_Error (AT91C_BASE_US1))
{
AT91C_BASE_US1->US_CR = AT91C_US_RSTSTA;
AT91C_BASE_AIC->AIC_EOICR = 0 ;
return;
}
//* Disable all interrupts
AT91C_BASE_US1->US_IDR = (0xFFFFFFFF);
if( status & AT91C_US_TXEMPTY ){DBGU.PrintString("\n\rAT91C_US_TXEMPTY\n\r");}
if( status & AT91C_US_RXBUFF )
{
DBGU.PrintString("\n\rAT91C_US_RXBUFF\n\r");
}
if( status & AT91C_US_TXBUFE ){DBGU.PrintString("\n\rAT91C_US_TXBUFE\n\r");}
if( status & AT91C_US_TIMEOUT ){DBGU.PrintString("\n\rAT91C_US_TIMEOUT\n\r");}
if( status & AT91C_US_ENDTX )
{
memcpy(InBuf,RxBuffer,Rx_Len);
AT91F_US_ResetRx(AT91C_BASE_US1);
AT91F_US_ReceiveFrame (AT91C_BASE_US1,RxBuffer,Rx_Len,0,0 );
AT91F_US_EnableIt(AT91C_BASE_US1,AT91C_US_ENDRX); //AT91C_US_RXRDY);

}
if( status & AT91C_US_ENDRX)
{
if( (RxBuffer[0]== Rx_Addr) && (RxBuffer[1] == Rx_Code) && (RxBuffer[Rx_Len-1]== us1.CalcCRC(RxBuffer,Rx_Len-1) ))
{
memcpy(TxBuffer,OutBuf,Tx_Len);
AT91F_US_ResetTx(AT91C_BASE_US1);
AT91F_US_SendFrame(AT91C_BASE_US1, TxBuffer,Tx_Len,0,0);
AT91F_US_EnableIt(AT91C_BASE_US1,AT91C_US_ENDTX); //AT91C_US_RXRDY);


}
else
{

AT91F_US_ResetRx(AT91C_BASE_US1);
AT91F_US_ReceiveFrame (AT91C_BASE_US1,RxBuffer,Rx_Len,0,0 );
AT91F_US_EnableIt(AT91C_BASE_US1,AT91C_US_ENDRX); //AT91C_US_RXRDY);
}

}

AT91C_BASE_US1->US_CR = AT91C_US_RSTSTA;
AT91C_BASE_AIC->AIC_EOICR = 0 ;

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