Jump to content

    

EugenB2

Участник
  • Content Count

    13
  • Joined

  • Last visited

Community Reputation

0 Обычный
  1. Еще раз стандартный startup посмотреть надо, там была ошибка, не восстанавливались флаги после выхода из прерывания. IRQ_Handler_Entry: ;- Manage Exception Entry ;- Adjust and save LR_irq in IRQ stack sub lr, lr, #4 stmfd sp!, {lr} ;- Save and r0 in IRQ stack stmfd sp!, {r0} mrs r0, spsr stmdb sp!,{r0} ; Save the context of the current task. !!!!!! ;- Write in the IVR to support Protect Mode ;- No effect in Normal Mode ;- De-assert the NIRQ and clear the source in Protect Mode ldr r14, =AT91C_BASE_AIC ldr r0 , [r14, #AIC_IVR] str r14, [r14, #AIC_IVR] ;- Enable Interrupt and Switch in Supervisor Mode msr CPSR_c, #ARM_MODE_SVC ;- Save scratch/used registers and LR in User Stack stmfd sp!, { r1-r11, r12, r14} ;- Branch to the routine pointed by the AIC_IVR mov r14, pc bx r0 ;- Restore scratch/used registers and LR from User Stack ldmia sp!, { r1-r11, r12, r14} ;- Disable Interrupt and switch back in IRQ mode msr CPSR_c, #I_BIT | ARM_MODE_IRQ ;- Mark the End of Interrupt on the AIC ldr r14, =AT91C_BASE_AIC str r14, [r14, #AIC_EOICR] ldmia sp!,{r0} ; и здесь вот так !!!!!!!! msr SPSR_cxsf,r0 ; и здесь вот так !!!!!!!! ;- Restore SPSR_irq and r0 from IRQ stack ldmia sp!, {r0} ;- Restore adjusted LR_irq from IRQ stack directly in the PC ldmia sp!, {pc}^
  2. Проблему с 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.
  3. Если еще актуально.... Эта программа вообще не должна работать как надо. Кстати, не хватает более подробного описания с какой максимальной частотой подается сигнал на вход пина, периодичный ли это сигнал или просто носит случайный характер и длительность. От этого сильно зависит как писать. ISR(TIMER2_COMPA_vect) { cli(); if (check_num_pin0 & check_pinA) { T2_0=TCNT1; --------------- так нельзя делать потому как неизвестно сколько же будет пропущено тактов с num_pin0 и на какой момент тогда придется это прерывание таймера counterA+=(T2_0-T1_0); } ISR(PCINT0_vect) { cli(); if (check_num_pin0 & check_pinA) // Высокий уровень { T1_0=TCNT1; } else // Низкий уровень { T2_0=TCNT1; ------------- А если счетчик пару раз переполниться пока сигнал в 1 будет? Что тогда посчитается в итоге? Неверно! counterA+=(T2_0-T1_0); } PCIFR=0; sei(); }
  4. А у меня была обратная проблема с USART - возникало Spurious Interrupt из-за AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE пришлось сменить на AT91C_AIC_SRCTYPE_POSITIVE_EDGE. Но в таймерах я всегда AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE использовал изначально и проблем не было таких. А вообще SAM7S довольно глючный контроллер... errata "радует", хотя по TC там нет ничего. Да... и, если в IAR пишется, то почему бы не пользоваться стандарными библиотечными функциями :rolleyes: : AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< AT91C_ID_TC1 ); AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC1, TIMER1_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, TimerIRQHandler1 );
  5. Ндаа. Радость была недолгой. Вставил во FreeRTOS, после prvSetupTimerInterrupt - это конфиг таймера шедулера - зависает все ((. подправил исходничек и вуаля на FreeRTOS тоже заработало mmu_sam9xe_2.zip ============== Кстати, что за глюк форума, не дает отредактировать сообщение.
  6. TWI в sam7s

    Такого метода по реанимации TWI я еще не пробывал )), кстати, у меня была дурная идея переписать весь SAM7S TWI под прерывания, чтобы избавиться от глюков. В итоге сделал софтовый и все работает без проблем. Аппаратный же... после зависания никаким образом, даже ресетом всего усройства, не выводился из этого состояния, тока выключение питания ((.
  7. Спасибо за файлик. После некоторых его исправлений я наконец-то получил таки мои 200мипсов! Я так подумал, а почему бы не разместить TLB таких объемов во FLASH(и ОЗУ не надо тратить и должно врое работать все), и разместил, залил вуаля, все также нормально(вроде нормально) работает. mmu_sam9xe.zip
  8. Cам в догадках... \ ??testit_0: \ 00000008 10109FE5 LDR R1,??testit_1 ;; 0xd59f80 единственное обращение к памяти, а производительности особо не прибавилось \ 0000000C 010050E1 CMP R0,R1 \ 00000010 0100002A BCS ??testit_2 \ 00000014 010090E2 ADDS R0,R0,#+1 \ 00000018 FAFFFFEA B ??testit_0 468 } \ ??testit_2: \ 0000001C 1EFF2FE1 BX LR ;; return
  9. Получается что да, если с MMU. Ищу вот пример реализации... Да полно уже нароботок на SAM7S, а вот с NXP тоже не так все гладко. Там оказывается, что ДМА реализован совершенно не так, как в атмелах. Есть несколько каналов ДМА на ВСЮ периферию и крутись как хочешь. Вот у меня были потоковые приложения, где вводилась инфа через 4 порта посредством PDC на постоянке. А если бы на NXP, то все, уперся бы в стену. Потому как каналы все были бы заняты. Но зато в NXP есть DMA SRAM to SRAM... )) и нет глюков с периферией таких.
  10. Почитал даташит по MMU, понял, что можно закопаться в написании с нуля сего дела. Полазил по форуму, по гуглу, что-то нет примеров реализации MMU. Может, у кого есть чего?
  11. Как раз им и пользуюсь, но ничего такого в коде и не видел.
  12. Спасибо, покопаю в этом направлении.
  13. Имеется платка с SAM9XE512, все запускает, шьется, работает. Но есть одно неприятное НО. Решил я затестить производительность сей штуки. Сделал тупо просто: t=GetTickCount(); 1ms тики for(k=0;k < 6600000; k++); подобрал, чтобы 1секунду примерно t=GetTickCount()-t; равно 1000 (вообще сделал вывод в DEBUG и компом проверил отсчет 1 секунды) Итак получаем в дизасме(позже выложу), что цикл занимает 5 инструкций, одна из них 2такта . Итого 7 тактов. Итак 7*6600000=46200000 46 MIPS Потом включаю ICache. Вуаля, производительность сразу в два раза 92мипса. А теперь вопрос! Где обещанные 200MIPS????? Или я где-то ошибся?