Hello, I have take a piece of source at http://www.arm.com and tried to compile it using the CARM compiler. The code is shown below:
/* NewState=1 will enable IRQ, NewState=0 will disable IRQ */ /* ARM core must be in a privileged mode, e.g. supervisor */ void ChangeIRQ(unsigned int NewState) { int my_cpsr; __asm { MRS my_cpsr, CPSR /* get current program status */ ORR my_cpsr, my_cpsr,#0x80 /* set IRQ disable bit flag */ BIC my_cpsr, my_cpsr, NewState, LSL #7 /* reset IRQ bit with new value */ MSR CPSR_c, my_cpsr /* store updated program status */ } } void main(void) { __asm{MSR CPSR_c, #0x13} //Go into Supervisor Mode ChangeIRQ(0); while(1) { } }
"I get the asm error" What asm error? Post the full text of the message - after looking up the message in the Manual, of course... http://www.keil.com/support/man/docs/ca/ca_errors.htm
Oh, the error I wrote in the subject:
*** Error C197 in-line assembly error
http://www.keil.com/support/man/docs/ca/ca_c197.htm Note that the usage of inline assembler is entirely compiler-specific. You say you just took this code off the ARM site - did you check that it is compatible with Keil's syntax?
Ok, thanks I didn't know that. I just thought that when they said at ARM.com, that this was the properly way to do it, when in ARM mode and in SUPERVISOR mode, it could be done. Sorry, but I don't know assembly yet, so i'm a bit green when it comes to using inline. You shouldn't have some code laying for disabling interrupt using code for the CARM compiler then?
The following code should do your job. Please note that the function(s) containing inline-assembly must use the proper mode of operation - either ARM or THUMB mode. If none is specified, CA defaults to thumb which causes ARM-instructions to be illegal . You can specify the mode by using #pragma ARM/THUMB or by explicitely using __arm/__thumb in the function definition as shown in the example (commented out). The LDAV instruction is a pseudo instruction which loads the value of a parameter or an automatic variable. 'my_cpsr' has been replaced by register R0.
#pragma ARM // use ARM mode void ChangeIRQ (unsigned int NewState) /*__arm*/ { //int my_cpsr; // __asm { AND R0,R0,#0 // clear R0 (used for 'my_cpsr') MRS R0,CPSR // my_cpsr, CPSR ORR R0,R0,#0x80; // my_cpsr, my_cpsr,#0x80 LDAV R1,R10,NewState // load parameter-value 'NewState' into R1 BIC R0,R0,R1,LSL #7 // my_cpsr, my_cpsr, NewState, LSL #7 MSR CPSR_c, R0 // CPSR_c,my_cpsr } } void main(void) /*__arm*/ { __asm {MSR CPSR_c, #0x13} // Go into Supervisor Mode ChangeIRQ (0); while (1) { } }
Thanks Peter, I will try this as soon as I come home to my development tool and target.
Actually you can find information about this also in our support knowledgebase: http://www.keil.com/support/docs/2991.htm In most cases, just enter the error number to get a related answer on the search field of http://www.keil.com/support. Reinhard
Peter, I tried to compile the piece of source and it went well, but it doesn't seem to have any effect. If I try to send something via the UART using THRE interrupt and I call the ChangeIrq(1); inside main, it just keeps sending via the UART. I should mean, that when global IRQ is disabled, the UART shouldn't send any more, when it needs THRE to send the next char.
Sorry, but what you are asking seems to be out of context. Take a look to: http://www.keil.com/download/docs/lpc2100_intsio.zip.asp Maybe this is the solution of your problem. Reinhard
ok, so where should I place the question if I just want to know how to disable global interrupts so I don't get disturbed by: timer, uart and external interrupts, while writing changes to an table and using the CARM compiler?
For this we have implemented __swi functions. Take a look to: http://www.keil.com/support/docs/2990.htm Reinhard
Thanks, so you mean that I can just use the __swi and write to my table inside this function and then I will not get interrupted by any IRQ!
YES