.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
I realize that. But all you have to do is diddle bits in a couple registers and they work. In this thing they're disabled. I diddle all the right registers and they should work, but they don't because somebody thought it made sense to make sure they couldn't work without doing something that should have already been done in the startup code. Weird!all interrupts on a PIC are disabled until you enable them.
I'm thinking more like in this piece of crt.s codeWhy not just comment this out:
and see what that does. Instead of turning them on later do it so its always on.Code:.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
#include "LPC214x.h"
#define PLOCK 0x400
#define IRQ_MASK 0x00000080
void init(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")));
unsigned enableIRQ(void);
unsigned disableIRQ(void);
unsigned restoreIRQ(unsigned oldCPSR);
unsigned int cp;
int main(void)
{
int i;
IODIR0 = 0x30600000;
IOCLR0 = 0x30600000; //LEDs off
init();
T0TCR = 0x02; //reset counter
T0IR = 0xff;
T0MCR = 0x0003; //interrupt and reset on MR0
T0MR0 = 0x0000ffff; //compare-hit count
VICVectCntl0 = 0x00000024; //use it for Timer 0 Interrupt:
VICVectAddr0 = (unsigned)&IRQ_Routine; //set interrupt vector in 0
VICIntEnable = 0x00000010; //enable TIMER0 interrupt
T0TCR = 0x01; //enable Timer0
cp = enableIRQ();
while(1){
i=0;
i=1;
}
}
void IRQ_Routine(void)
{
int i;
IOSET0 = 0x30600000; //4 LEDs blink
for(i=0;i<0x0000ffff;i++);
IOCLR0 = 0x30600000;
T0IR = 0x01; //clear interrupt
VICVectAddr0 = 0; //end of interrupt - dummy write
}
void init(void)
{
PLLCFG=0x24; //set multiplier/divider values
PLLFEED=0xaa;
PLLFEED=0x55;
PLLCON=0x01; //enable PLL
PLLFEED=0xaa;
PLLFEED=0x55;
while(!(PLLSTAT & PLOCK)); //wait for the PLL to lock to set frequency
PLLCON=0x3; //connect the PLL as the clock source
PLLFEED=0xaa;
PLLFEED=0x55;
MAMCR=0x02; //enable MAM
MAMTIM=0x04; //set number of clocks for flash memory fetch
VPBDIV=0x01; //set peripheral clock(pclk) to system clock(cclk)
}
void FIQ_Routine(void){
while (1) ;
}
void SWI_Routine(void){
while (1) ;
}
void UNDEF_Routine(void) {
while (1) ;
}
static inline unsigned asm_get_cpsr(void)
{
unsigned long retval;
asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ );
return retval;
}
static inline void asm_set_cpsr(unsigned val)
{
asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) );
}
unsigned enableIRQ(void)
{
unsigned _cpsr;
_cpsr = asm_get_cpsr();
asm_set_cpsr(_cpsr & ~IRQ_MASK);
return _cpsr;
}
unsigned disableIRQ(void)
{
unsigned _cpsr;
_cpsr = asm_get_cpsr();
asm_set_cpsr(_cpsr | IRQ_MASK);
return _cpsr;
}
unsigned restoreIRQ(unsigned oldCPSR)
{
unsigned _cpsr;
_cpsr = asm_get_cpsr();
asm_set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK));
return _cpsr;
}
void IRQ_Routine(void)
{
int i;
IOSET0 = 0x30600000; //4 LEDs blink
for(i=0;i<0x0000ffff;i++);
IOCLR0 = 0x30600000;
T0IR = 0x01; //clear interrupt
[b] VICVectAddr0 = 0; //end of interrupt - dummy write[/b]
//The above bold changes the address again
}
void IRQ_Routine(void)
{
int i;
IOSET0 = 0x30600000; //4 LEDs blink
for(i=0;i<0x0000ffff;i++);
IOCLR0 = 0x30600000;
T0IR = 0x01; //clear interrupt
VICVectAddr = 0x0000; //end of interrupt - dummy write
}
Oops!i think its:
void IRQ_Routine(void)
{
int i;
IOSET0 = 0x30600000; //4 LEDs blink
for(i=0;i<0x0000ffff;i++);
IOCLR0 = 0x30600000;
T0IR = 0x01; //clear interrupt
VICVectAddr = 0x0000; //end of interrupt - dummy write
T0TCR = 0x02;
T0TCR = 0x01; //Added this
}
Shouldn't be necessary. It'll wrap around. I don't care how long it takes at this point.how about resetting the counter after the ISR like:
#include "LPC214x.h"
#define PLOCK 0x400
#define IRQ_MASK 0x00000080
void init(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")));
unsigned enableIRQ(void);
unsigned disableIRQ(void);
unsigned restoreIRQ(unsigned oldCPSR);
int main(void)
{
int i;
unsigned cp;
IODIR0 = 0x30600000;
IOCLR0 = 0x30600000; //LEDs off
init();
T0TCR = 0x02; //reset counter
T0IR = 0xff;
T0MCR = 0x0003; //interrupt and reset on MR0
T0MR0 = 0x00ffffff; //compare-hit count
VICVectCntl0 = 0x00000024; //use it for Timer 0 Interrupt:
VICVectAddr0 = (unsigned)IRQ_Routine; //set interrupt vector in 0
VICIntEnable = 0x00000010; //enable TIMER0 interrupt
T0TCR = 0x01; //enable Timer0
cp = enableIRQ();
while(1){
i=0;
i=1;
}
}
void IRQ_Routine(void)
{
int i;
IOSET0 = 0x30600000; //4 LEDs blink
for(i=0;i<0x0000ffff;i++);
IOCLR0 = 0x30600000;
T0IR = 0x01; //clear interrupt
VICVectAddr = 0; //end of interrupt - dummy write
}
void init(void)
{
PLLCFG=0x24; //set multiplier/divider values
PLLFEED=0xaa;
PLLFEED=0x55;
PLLCON=0x01; //enable PLL
PLLFEED=0xaa;
PLLFEED=0x55;
while(!(PLLSTAT & PLOCK)); //wait for the PLL to lock to set frequency
PLLCON=0x3; //connect the PLL as the clock source
PLLFEED=0xaa;
PLLFEED=0x55;
MAMCR=0x02; //enable MAM
MAMTIM=0x04; //set number of clocks for flash memory fetch
VPBDIV=0x01; //set peripheral clock(pclk) to system clock(cclk)
}
void FIQ_Routine(void){
while (1) ;
}
void SWI_Routine(void){
while (1) ;
}
void UNDEF_Routine(void) {
while (1) ;
}
static inline unsigned asm_get_cpsr(void)
{
unsigned long retval;
asm volatile (" mrs %0, cpsr" : "=r" (retval) : /* no inputs */ );
return retval;
}
static inline void asm_set_cpsr(unsigned val)
{
asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) );
}
unsigned enableIRQ(void)
{
unsigned _cpsr;
_cpsr = asm_get_cpsr();
asm_set_cpsr(_cpsr & ~IRQ_MASK);
return _cpsr;
}
unsigned disableIRQ(void)
{
unsigned _cpsr;
_cpsr = asm_get_cpsr();
asm_set_cpsr(_cpsr | IRQ_MASK);
return _cpsr;
}
unsigned restoreIRQ(unsigned oldCPSR)
{
unsigned _cpsr;
_cpsr = asm_get_cpsr();
asm_set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK));
return _cpsr;
}
VICVectAddr0 = (unsigned)IRQ_Routine;
VICVectAddr0 = (unsigned)&IRQ_Routine;
Will you be using Eclipse/yagarto? If you're going to be running Crossworks you don't need any of this stuff.I don't want to hassle you but can i get a copy of the code and startup please? So when i get mine i can study it also.
Yes, I know. VICVectAddr0 is the vector address for IRQ slot 0, which is the highest priority vectored IRQ. Only FIQ gets serviced at higher priority.Code:VICVectAddr0 = (unsigned)IRQ_Routine;
This is used to tell the uC that ISR routine that you want it to jump to that location on the ISR set using "VICVectCntl0".
Yup. Your idea made sense, but I looked at other code and nobody puts the &, so I guess it's not necessary.Since its a address i suggested using the & sign as:
Code:VICVectAddr0 = (unsigned)&IRQ_Routine;
But as we can see its not needed.
You don't need to cross compile. It's the same free open-source GCC compiler.The thing i dont understand is. Can i cross compile? Like use code made using yagarto with crossworks? Are they compatible? Or will there be many differences?
Which are you sticking with?
Umm... Why? That's the board I have.Thought you would find this interesting:
LPC2148 PROTOTYPE DEVELOPMENT BOARD
Yes it is.I was referring to the software at the bottom but i just remembered you said yours came with a cd i assume thats on it already then.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?