Subject:
|
[long] Interrupt programming, buggy code
|
Newsgroups:
|
lugnet.robotics.rcx
|
Date:
|
Tue, 2 Mar 2004 14:59:14 GMT
|
Viewed:
|
3441 times
|
| |
| |
Hi all,
I am currently programming the Lego RCX at low-level (plain C) using the
GCC cross-compiler for Hitachi H8/300 and Kekoa Proudfoot's LibRCX. In
fact, I'm designing exercises for students that learn micro-controller
programming. Therefore, I don't even use the ROM routines (except those
that deals with the lcd display).
I managed to deal with motors and touch sensors using both the Hitachi
Hardware Manual and Kekoa Proudfoot's "RCX Internals".
I know want to program the H8/300 interrupts. I've managed to define an
OCIA handler, but I'm afraid I've missed something since I can't get it
to work right. This handler only increments a global and then displays
its value on the LCD. That should be easy, but... When I run my program,
the LCD displays 0, then 1, then 2, then 3, then... Then the RCX hangs,
and I can't get anything from it. I have to remove the batteries and put
them in again to "reboot" the crashed RCX.
I just don't see what I'm doing wrong, so I'm asking if anybody has an
idea. In case such gurus lie around here, I post my C code below.
Thanks.
/* My buggy code */
int count;
#define mask_it() asm ("orc #0x80, ccr");
#define unmask_it() asm ("andc #0x7f, ccr");
#define OCIA_HANDLER *( (volatile word *) 0xfda2)
void ocia_handler(void) __attribute__ ((interrupt_handler));
void ocia_handler(void) {
FRT_TCSR &= ~bit3; /* clear output compare flag A */
count++;
debug_value(count);
}
int main (void) {
count = 0;
/* debug_value is just a call to ROM routine at 0x1ff2
* that displays an integer */
debug_value(count);
OCIA_HANDLER = (word)ocia_handler; /* install OCIA handler */
/* Timer clock selection: use div 32 clock */
FRT_TCR |= bit1; /* CSK1 <- 1 */
FRT_TCR &= ~bit0; /* CSK0 <- 0 */
FRT_TCSR = bit0; /* Clear FRT on compare-match A */
FRT_TOCR &= ~bit4; /* Compare timer to OCRA */
FRT_OCRA = 50000; /* Interrupt every 100 ms */
FRT_FRC = 0; /* Clear free running timer */
FRT_TCSR &= ~bit3; /* Clear output compare flag A */
/* Enable OCIA - see p. 117
* ie an interrupt is generated when FRT == OCRA
*/
FRT_TIER |= bit3;
/* Unmask interrupts */
unmask_it();
while (!prgm_pressed()) {
/* Wait for "pgrm"button to be pressed */
}
return 0;
}
--
Benjamin Sigonneau
PhD student, LANDE project
IRISA-INRIA, Campus de Beaulieu, 35042 Rennes cedex, France
Tél: +33 (0) 2 99 84 73 29
|
|
Message has 3 Replies: | | RE: [long] Interrupt programming, buggy code
|
| Having fun yet :-) There are a few things you might want to keep in mind when writing ISRs for the RCX... First, avoid calling into the ROM from an interrupt handler. You never know how long they take, and you may in fact be hitting another OCIA (...) (21 years ago, 2-Mar-04, to lugnet.robotics.rcx)
| | | Re: [long] Interrupt programming, buggy code
|
| (...) All I can give you is guesses. There are pleny of gurus here who will know the answer. Do you know if the display_debug() routine or any of the things it uses depends on the interrupts you are taking over? If default interrupt handler provides (...) (21 years ago, 2-Mar-04, to lugnet.robotics.rcx)
| | | Re: [long] Interrupt programming, buggy code
|
| Hi Benjamin, When you declare your ISR as an interrupt_handler, GCC terminates the function with an "rte" instead of an "rts". The ROM code that dispatches the interrupt to your function is already doing the rte so your function should not. Here's (...) (21 years ago, 2-Mar-04, to lugnet.robotics.rcx)
|
7 Messages in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|