To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcxOpen lugnet.robotics.rcx in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / 2370
2369  |  2371
Subject: 
Re: [long] Interrupt programming, buggy code
Newsgroups: 
lugnet.robotics.rcx
Date: 
Tue, 2 Mar 2004 17:54:47 GMT
Viewed: 
3426 times
  
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
the ROM dispatch code:

04cc: mov.w  r6,@-e7
04ce: mov.w  @0xfda2:16,r6
04d2: jsr    @r6
04d4: mov.w  @r7+,r6
04d6: rte

Instead, you could remove the interrupt_handler attribute and preserve the
scratch registers like so:

void ocia_handler(void) {
  __asm__ ("push r0");
  __asm__ ("push r1");
  __asm__ ("push r2");
  __asm__ ("push r3");

  FRT_TCSR &= ~bit3; /* clear output compare flag A */
  count++;
  debug_value(count);

  __asm__ ("pop r3");
  __asm__ ("pop r2");
  __asm__ ("pop r1");
  __asm__ ("pop r0");
  }

Also, the C compiler that generated the ROM code uses a different calling
convention than GCC and r6 is trashed by the debug_value() call.  GCC isn't
expecting this, so it may be prudent to wrap calls to debug_value() with a push
and pop of r6.  It won't cause a problem in your current code because the ROM
dispatch code already preserves r6 for your ISR.

HTH,

Mark

In lugnet.robotics.rcx, Benjamin Sigonneau wrote:
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;
}



Message has 3 Replies:
  RE: [long] Interrupt programming, buggy code
 
Much better and more accurate answer from Mark - who knows a lot more about GCC that I do :-) I should stick to commenting on assembly language stuff. Ralph (...) <snippage> (21 years ago, 2-Mar-04, to lugnet.robotics.rcx)
  Re: [long] Interrupt programming, buggy code
 
(...) Eh... Never mind this bit. I just had a gander at Kekoa's rcxlib and he already handles this correctly in debug_value(). Should've known! :-) Mark (21 years ago, 2-Mar-04, to lugnet.robotics.rcx)
  Re: [long] Interrupt programming, buggy code
 
On Tue, 2 Mar 2004 17:54:47 GMT "Mark Riley" <markril@hotmail.com> wrote: Hi Mark, (...) [snip] (...) [snip] And that was it, indeed! Many to you, as well as Ralph and Kevin who tried to help me. There shouldn't be much trouble for me I think (if we (...) (21 years ago, 2-Mar-04, to lugnet.robotics.rcx)

Message is in Reply To:
  [long] Interrupt programming, buggy code
 
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 (...) (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

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR