Здравствуйте!
Есть gcc version 3.4.0-macraigor1 и упорный камень LPC2106
Тема: "Опять 25" поморгать светиком по прерыванию таймера.
?нужны ли какие нибудь __attribute__ обработчику прерывания таймера void TIMER0_ISR (void); и как их корректно записать. ИНХО как минимум нужно сказать компилятору что данная подпрограмма работает в режиме ARM.
Не моргает зараза :-( А вот если не делать ENABLE_INTERRUPTS и не настроивать VIC, и в основном бесконечном цикле проверять флаг прерывания таймера то усё моргает как надо, то есть инициализация таймера прошла без косяков.
?на счёт __attribute__ мануалы курил, смотрел исходники arm.c но не понятен синтаксис, можно ли прописывать несколько атрибутов и как это делать (совершенно нет ярких примеров, а интернету потрачено на поиск экзампелей - уйма) Во всех ли случаях __attribute__ заменяет #pragma? особенно что касается обработчиков прерываний, и указаний какой код генерить arm/thumb/interwork.
Код приводится полностью. Запускается из RAM, ремап делается... ну что ещё нужно?!
/**********************************************************/ void Initialize(void); void feed(void); void Timer0_IRQ_Init (void); void Timer0_Init(void); void LPC210xInitVIC(void);
void IRQ_Routine (void) __attribute__ ((interrupt("IRQ"))); void FIQ_Routine (void) __attribute__ ((interrupt("FIQ"))); void SWI_Routine (void) __attribute__ ((interrupt("SWI"))); void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF"))); void TIMER0_ISR (void); void DefDummyInterrupt(void);
#include "LPC210x.h"
#define ENABLE_INTERRUPTS asm volatile ( \ "mrs r3,cpsr;" \ "bic r3,r3,#0xC0;" \ "msr cpsr,r3" \ : \ : \ : "r3" \ )
int main (void) { // Initialize the system Initialize(); Timer0_Init(); Timer0_IRQ_Init(); ENABLE_INTERRUPTS;
IODIR |= 0x0000FFFF; while (1) { /* Если раскоментарить нижнюю строку, но при инициализвции не разрешать прерывания, то светик буде моргать, значит прерывания от таймера всётаки генерятся.
*/ //if (TIMER0_IR !=0) {TIMER0_ISR();}; } }void DefDummyInterrupt(void) {} void LPC210xInitVIC(void) { // Setup interrupt controller. VICProtection = VICIntSelect = 0; // VICIntEnClr = 0xffffffff; // Disable all interrupts VICDefVectAddr = (unsigned int)&DefDummyInterrupt; }
#define PLOCK 10<<1 void Initialize(void) { PLLCFG=0x25; feed(); PLLCON=0x1; feed(); while(!(PLLSTAT & PLOCK)) ; PLLCON=0x3; feed(); // Enabling MAM and setting number of clocks used for Flash memory fetch (4 cclks in this case) MAMCR=0x2; MAMTIM=0x3; /* Initialize MEMAP - re-map vector table to RAM */ MEMMAP = 0x02; VPBDIV=0x1; LPC210xInitVIC(); }
void feed(void) {PLLFEED=0xAA;PLLFEED=0x55;}
// Timer interrupt handler void TIMER0_ISR(void) { static unsigned char i=0; if ((i=!i)==0) {IOSET=0xFFFF;} else {IOCLR=0xFFFF;}; TIMER0_IR = 0xff; // Clear timer 0 interrupt line. }
//XTAL frequency in Hz #define XTALFREQ 11059200 * 6 //66355200
//pclk must always be XTALFREQ/4 when using the ROM monitor. #define PCLKFREQ (XTALFREQ/4) #define Delay_ms = 1000 #define Delay_HEX = - Delay_ms / PCLKFREQ #define TIMER0_START (TIMER0_TCR = 1)
void Timer0_Init(void) { IOSET = 0xFFFF;// red led on TIMER0_TCR = TIMER0_PC = TIMER0_CCR = TIMER0_EMR = 0;/* TIMER0_MR0 = 0x0024E1C0; TIMER0_MCR = 3; // Reset and interrupt on MR0 (match register 0). TIMER0_START; }
#define VIC_TIMER0_bit (1 << VIC_TIMER0) void Timer0_IRQ_Init (void){ VICIntSelect &= ~VIC_TIMER0_bit; // IRQ on timer 0 line. VICVectAddr0 = (unsigned int)&TIMER0_ISR; VICVectCntl0 = 0x20 | VIC_TIMER0; // Enable vector interrupt for timer 0.*/ VICIntEnable |= 0xFFFF;//VIC_TIMER0_bit; // Enable timer 0 interrupt. }
void IRQ_Routine (void) { unsigned int vector = VICVectAddr; void (*interrupt_function)() = (void(*)())vector; (*interrupt_function)(); VICVectAddr = 0; } void FIQ_Routine (void) { while (1) ;} void SWI_Routine (void) { while (1) ;} void UNDEF_Routine (void) { while (1) ;}
C уважением, Герасимов.
;-)