|
|
  |
Пробемы с инициализацией SPI и USART |
|
|
|
Dec 28 2007, 11:28
|
Участник

Группа: Новичок
Сообщений: 36
Регистрация: 26-10-07
Пользователь №: 31 739

|
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?
|
|
|
|
|
Dec 28 2007, 13:15
|
Участник

Группа: Новичок
Сообщений: 36
Регистрация: 26-10-07
Пользователь №: 31 739

|
По отдельности то все работает...какие именно биты чистить?
|
|
|
|
|
Dec 28 2007, 14:25
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

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

Группа: Новичок
Сообщений: 36
Регистрация: 26-10-07
Пользователь №: 31 739

|
Пока небудет __enable_interrupt(); прерывания не срабатывают.
|
|
|
|
|
Dec 29 2007, 06:17
|

Частый гость
 
Группа: Свой
Сообщений: 152
Регистрация: 11-10-05
Из: Воронеж
Пользователь №: 9 491

|
Цитата(Daermon @ Dec 29 2007, 08:20)  Пока небудет __enable_interrupt(); прерывания не срабатывают. не понял, к чему это? если не вызывать init_spi(), SPI не включится, прерывания по нему происходить не будут, разрешай-не разрешай. если прерывания включаются в init_usart(), то когда его не вызываешь, тоже прерывания не происходят - не разрешены. а когда вызываешь обе процедуры, то условия для зависания создаются.
|
|
|
|
|
Jan 9 2008, 05:53
|
Участник

Группа: Новичок
Сообщений: 36
Регистрация: 26-10-07
Пользователь №: 31 739

|
Вот как раз и непонятно почему условия для зависания создаются? В обработчиках прерывания статус регистры читаю, на выходе из прерывания ставлю AT91C_BASE_US1->US_CR = AT91C_US_RSTSTA; AT91C_BASE_AIC->AIC_EOICR = 0 ;
Поэтому не понятно что может привести к зацикливанию на прерывании
|
|
|
|
|
Jan 10 2008, 08:27
|
Участник

Группа: Новичок
Сообщений: 36
Регистрация: 26-10-07
Пользователь №: 31 739

|
Обошел проблему путем исключения прерывания 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 ; };
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|