Цитата(aaarrr @ Jul 18 2010, 01:09)
Spurious Interrupt возникает по вполне определенным причинам и не является проблемой, если, конечно, не снабжено зависающей заглушкой (в атмеловских примерах встречался такой маразм).
К IAR'у, слава богу, данные функции никакого отношения не имеют. Для записи значения в регистр можно обойтись и без "библиотек".
А если нужно что-то сложнее, то надежнее использовать собственную голову, дабы не украшать программу подобными чудесами программистской мысли:
Код
//*----------------------------------------------------------------------------
//* \fn AT91F_SSC_SetBaudrate
//* \brief Set the baudrate according to the CPU clock
//*----------------------------------------------------------------------------
__inline void AT91F_SSC_SetBaudrate (
AT91PS_SSC pSSC, // \arg pointer to a SSC controller
unsigned int mainClock, // \arg peripheral clock
unsigned int speed) // \arg SSC baudrate
{
...
}
Проблему с Spurious Interrupt я и решил убиранием заглушки плюс AT91C_AIC_SRCTYPE_POSITIVE_EDGE.
Согласен, что не все функции библиотечные хороши, что там может быть заложена "бомба" ))), но куда нагляднее и красив код:
AT91F_AIC_Configure(AT91C_BASE_AIC, irq_id, DEBUG_INTERRUPT_LEVEL,DEBUG_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, newHandler );
AT91F_AIC_EnableIt (AT91C_BASE_AIC, irq_id);
ЧЕМ вот это нагромождение:
/////////// AIC
unsigned int mask ;
mask = 0x1 << irq_id ;
//* Disable the interrupt on the interrupt controller
pAic->AIC_IDCR = mask ;
//* Save the interrupt handler routine pointer and the interrupt priority
pAic->AIC_SVR[irq_id] = (unsigned int) newHandler ;
//* Store the Source Mode Register
pAic->AIC_SMR[irq_id] = src_type | priority ;
//* Clear the interrupt on the interrupt controller
pAic->AIC_ICCR = mask ;
// AT91F_AIC_EnableIt
//* Enable the interrupt on the interrupt controller
pAic->AIC_IECR = 0x1 << irq_id ;
Тем более, к примеру, короткие функции все inline и очень наглядны для работы, чем вписывать регистры:
//*----------------------------------------------------------------------------
//* \fn AT91F_UDP_EpSet
//* \brief Set flag in the endpoint CSR register
//*----------------------------------------------------------------------------
__inline void AT91F_UDP_EpSet(
AT91PS_UDP pUDP, // \arg pointer to a UDP controller
unsigned char endpoint, // \arg endpoint number
unsigned int flag) // \arg flag to be cleared
{
pUDP->UDP_CSR[endpoint] |= flag;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_UDP_EpStatus
//* \brief Return the endpoint CSR register
//*----------------------------------------------------------------------------
__inline unsigned int AT91F_UDP_EpStatus(
AT91PS_UDP pUDP, // \arg pointer to a UDP controller
unsigned char endpoint) // \arg endpoint number
{
return pUDP->UDP_CSR[endpoint];
}
//*----------------------------------------------------------------------------
//* \fn AT91F_UDP_GetInterruptMaskStatus
//* \brief Return UDP Interrupt Mask Status
//*----------------------------------------------------------------------------
__inline unsigned int AT91F_UDP_GetInterruptMaskStatus( // \return UDP Interrupt Mask Status
AT91PS_UDP pUdp) // \arg pointer to a UDP controller
{
return pUdp->UDP_IMR;
}
А если в 10 местах использовать инит AIC, то совсем некрасиво.
Когда вы пользуетесь вызовами функций драйверов сети, i2c например, вы же не обращаетесь в регистры каждый раз напрямую игнорируя библиотечные вызовы. Есть библиотека(не важно эта или другая) и если что-то исправить надо в вызываемых функциях, то можно подправить исходник.
Чем сложнее процессор или контроллер, тем больше кода инита периферии и т.д., если сравнить с AVR, где раз два и сделал все что надо ).
Если данные библиотека не так удачна, то можно свою написать с основными для себя функциями и потом их везде использовать.
PS: Впрочем, я уж очень сгустил краски в ответе. Но я при написании стараюсь сразу убрать все прямые обращения к регистрам в свои библиотеки ))).
Если места не хватает, то да... приходиться потрошить все и убирать лишние библиотечные вызовы, но с такими объемами FLASH на ARM такие проблемы только на AVR мелких решать приходится ))).
Так что никак не могу сказать, что вы правы на все 100.
Сообщение отредактировал EugenB2 - Jul 20 2010, 07:50