Shop OBEX P1 Docs P2 Docs Learn Events
Handling both RTCC and WKEN_B interrupts — Parallax Forums

Handling both RTCC and WKEN_B interrupts

Keith MKeith M Posts: 102
edited 2005-03-17 15:53 in General Discussion
I looked through the standard books, datasheets, whatever, and didn't find my answer.

If I enter an ISR through a WKEN_B interrupt, does this reset/clear the RTCC?· Meaning, if I have RTCC set to overflow at 2us, and I trigger as a result of edge detection, will the next overflow happen 2us later or some amount less than 2us(ie whatever was left on the clock)?· Do I have to manually reset RTCC if I want this functionality(if so, how to?)

I'm guessing the counter (re)starts when I *leave* the ISR as a result of the "RETURNINT" SX/B command or the reti, retiw (IIRC) instructions.· This is the functionality I need.

Thanks.

Keith
·

Comments

  • pjvpjv Posts: 1,903
    edited 2005-03-13 22:17
    Hello Keith;

    The RTCC and RB edge detection are totally independent, although there is ony one interrupt vector, and that is at $000. When either RTCC overflows or an edge is detected, the processor switches to the interrupt routine at that $000 vector.

    During an ISR entry due to an edge detect event, the RTCC keeps counting as per normal. Should the value of the RTCC counter have been such that a rollover occurs while it was already in the ISR, then that occurrence would go unnoticed by the interrupt routine and must make specific code to poll the value of the RTCC, and deal with the roll-over in your (ISR) software.

    The RTCC is not cleared or adjusted by the processor when an edge detect interrupt occurs, and the next interrupt would occur at the normal next 2 uSec interval. Clearly you will have a conflict if the 2 uSec time roll-over occurs while you are already in an edge detect interrupt. Polling for this occurrence while in interrupt allows you to deal with that.

    Cheers,

    Peter (pjv)
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-03-13 22:27
    Depending on what priority you want to handle the two events, you can write your ISR to properly account for both events. If RTCC has priority, take the RTCC value, add the clock cycles to execute the ISR had the RTCC not occured, if the value overflows, reti immediately. If pin change is priority, store the current RTCC value, process the pin change when done compare the current RTCC with the stored RTCC, if overflow occured, handle the overflow event before returning.
    The first solution may not work if the overflow occurs in those few cycles it takes to compare and decide.
    In a nutshell the RTCC is not cleared, if this is the behavior you want, you'll have to clear it manually.
  • Michael ChadwickMichael Chadwick Posts: 80
    edited 2005-03-14 07:20
    The RTCC certainly keeps running through the interrupt, that is how it keeps track of how long your ISR takes.· When you exit with the RETIW instruction, and the twos complement of the desired RTCC interval in W, it backs off the RTCC the proper amount to cause it to roll over at the interval you select.

    We want an interval of 100 cycles ( 50 Mhz / 500Khz ) or 2 microseconds / .02 microseconds.· The RTCC interrupt happens when the RTCC goes from 255 to 0, so it is counting up during your interrupt.·
    Suppose your interrupt took 50 cycles, or half what we want as an interval.· When you do the RETIW with W holding -100, at the end just before the return, the RTCC gets loaded with 50 - 100 or -50 which means it will take it 50 cycles to hit again 0 and trip the interrupt.· Just what you want for regular periodic interrupts.

    But that isn't quite what we want.

    Remember, in the case of the MFM decoder, we want to use the RTCC as a one shot timer of sorts.·· And the interval you end up with isn't really too critical.· We want to sample a little bit longer than half a cell time, or 2 microseconds.· With no pre scaler on the RTCC we are looking at the 100 counts.

    What you want to have happen is for a B pin interrupt to happen so you are in sync,· shift that 1 bit into your bit accumulator or MFM shift register, whatever you want to call it.· You then want to load the RTCC register with 255-100 or· 155 and do a normal RETI.· The additional time just moves us out a little so we don't get an RTCC interrupt before a possible B edge detect.· If you don't get a transition before the 2 microseconds plus a little, the RTCC interrupt happens, you check the B pin WKPND register, and if it isn't set, you clock a 0 into your MFM shift register.· Then reload the timer as before to wait for the next (approximately) half bit boundary.

    To make it easier, you could always clear the RTCC at the start of an interrupt, no matter the cause.· At the end do the standard RETIW with the -100 value in W and the intervals will be close enough for jazz. The time should only be off by the difference in cycles from the start of the interrupt to the clear, which, should only be the interrupt latency of 3 cycles plus 1 if you always have the RTCC in register space and use CLR RTCC as the first instruction. If that is a problem, you can just off set the value of W before the RETIW.

    Here is my cut at it, tested on SXsim, seems to work the way I intended it to.· Boy that formatted code window has issues with tabs.......

    ;==============================================================================
    ;
    ; Title: Amiga MFM grabber
    ; Version: 1.0.0-0
    ; Desc:  SX28-to act as simple phase lock loop to snag MFM data
    ; Author: Mike Chadwick
    ; Created: 03/13/2005
    ; Modified:
    ; Released: 
    ;
    ;==============================================================================
    ;  Device Directives
    ;==============================================================================
      device SX28,oschs3,turbo,stackx,bor42,protect,watchdog
      Irc_cal IRC_SLOW
      freq 50_000_000
      reset Main
      LIST Q=37
    ;==============================================================================
    ;  Program Revision Levels and ID
    ;==============================================================================
     VERSION_MAJOR equ $01
     VERSION_MINOR equ $00
     REVISION      equ $00
     PLATFORM      equ $00
     
     ID 'MFM1001'
    ;==============================================================================
    ;               Revision History
    ;==============================================================================
    ;
    ; 1.0.0-0  Test Version, uses watchdog timer, enables brownout at 4.2V
    ;==============================================================================
    ;               NOTES
    ;==============================================================================
    ;
    ;
    ;==============================================================================
    ;   Global Includes
    ;==============================================================================
    error P1W 'Current Program Version:MFM ', VERSION_MAJOR, '.',VERSION_MINOR,'.',REVISION,'-',PLATFORM
    ; 
    ;==============================================================================
    ;  Defines to Activate Test Features
    ;==============================================================================
    ;
    ;==============================================================================
    ;   CONSTANTS
    ;==============================================================================
    ; Mode settings for the various I/O registers
      TRIS   equ $0F  ; 1 pin tristated, 0 pin outputs
      PLP    equ $0E  ; 1 pull up disabled, 0 pull up enabled
      LVL    equ $0D  ; 1 input level TTL, 0 input level CMOS
      ST     equ $0C  ; 1 disable schmidt trigger input, 0 enable schmidt trigger input
      WKEN   equ $0B  ; 1 disable wake up on pin, 0 enable wake up on pin
      WKED   equ $0A  ; 1 select falling edge wake up, 0 select rising edge wake up
      WKPND  equ $09  ; 1 edge detected since last clear, 0 no edge detected 
      CMP    equ $08  ; bit 7-Comparator enabled if 0
                      ; bit 6-Comparator output enabled if 0
                      ; bit 0 read comparator result
    ;==============================================================================
    ; Setup and enable RTCC interrupt, WREG register, RTCC/WDT prescaler
    ;==============================================================================
    ;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
    ; Virtual Peripheral Guidelines Tip:
    ;
    ; The suggested default values for the option register are:
    ; - Bit 7 set to 0: location $01 addresses the W register (WREG
    ; - Bit 5 set to 0: RTCC increments on internal transitions
    ; - Bit 3 set to 1: Prescaler assigned to WatchDog Timer
    ;
    ; If a routine must change the value of the option register (for example, to
    ; access the RTCC register directly), then it should restore the default value
    ; for the option register before exiting.
    ;
    ;?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?!?
    RTCC_ON  =  %10000000        ;Enables RTCC at address $01 (RTW hi)
                                 ;*WREG at address $01 (RTW lo) by default
    RTCC_ID  =  %01000000        ;Disables RTCC edge interrupt (RTE_IE hi)
                                 ;*RTCC edge interrupt (RTE_IE lo)
                                 ;enabled by default
    RTCC_INC_EXT  =  %00100000   ;Sets RTCC increment on RTCC pin transition (RTS hi)
                                 ;*RTCC increment on internal instruction (RTS lo)
                                 ;is default
    RTCC_FE  =  %00010000        ;Sets RTCC to increment on falling edge (RTE_ES hi)
                                 ;*RTCC to increment on rising edge (RTE_ES lo) is
                                 ;default
    RTCC_PS_ON   =  %00000000    ;Assigns prescaler to RTCC (PSA lo)
    RTCC_PS_OFF  =  %00001000    ;Assigns prescaler to WDT (PSA lo)
                                 ; prescaler Division Ratio         
                                 ; 2 1 0    RTCC    WDT   WDT      
    PS_000       =  %00000000    ; 0 0 0    1:2     1:1    0.016 sec
    PS_001       =  %00000001    ; 0 0 1    1:4     1:2    0.032 sec
    PS_010       =  %00000010    ; 0 1 0    1:8     1:4    0.064 sec
    PS_011       =  %00000011    ; 0 1 1    1:16    1:8    0.128 sec
    PS_100       =  %00000100    ; 1 0 0    1:32    1:16   0.256 sec
    PS_101       =  %00000101    ; 1 0 1    1:64    1:32   0.512 sec
    PS_110       =  %00000110    ; 1 1 0    1:128   1:64   1.024 sec
    PS_111       =  %00000111    ; 1 1 1    1:256   1:128  2.048 sec                                     
    
    ; we are set to have RTCC at $01, increment on internal instructions, prescaler assigned to
    ; WDT and longest prescaler interval
     
     
    OPTIONSETUP  equ  RTCC_ON|RTCC_PS_OFF|PS_111  ; the default option setup for this program.
     
    RTW  equ $80  ; 0 - register $01 is W, 1 - RTCC
    RTI  equ $40  ; 0 - RTCC roll over interrupt enabled, 1 - disabled
    RTS  equ $20  ; 0 - RTCC increments on internal instruction cycle, 1 - transition of RTCC pin
    RTE  equ $10  ; 0 - RTCC incrments on low to high transition, 1 - high to low
    PSA  equ $08  ; 0 - prescaler assigned to RTCC, 1 - prescaler assigned to Watch Dog Timer
    PS2  equ $04  ; prescaler Division Ratio 
    PS1  equ $02  ; 2 1 0    RTCC    WDT   WDT
    PS0  equ $01  ; 0 0 0    1:2     1:1    0.016 sec
                  ; 0 0 1    1:4     1:2    0.032 sec
                  ; 0 1 0    1:8     1:4    0.064 sec
                  ; 0 1 1    1:16    1:8    0.128 sec
                  ; 1 0 0    1:32    1:16   0.256 sec
                  ; 1 0 1    1:64    1:32   0.512 sec
                  ; 1 1 0    1:128   1:64   1.024 sec
                  ; 1 1 1    1:256   1:128  2.048 sec
    ;==============================================================================
     
    osc equ 50_000_000  ; assume 50 MHz oscillator
     
    ISR_freq equ 500_000
     
    ; protocol related constants
    ; the initial times 10 and subsequent +5 s are to force rounding to take place at the proper 
    ; points
    ; the final divide by 10 removes the initial factor of 10
    ; proper ISR rate to produce accurate baud rates is 307200, or 614400.
    ; actual ISR rate with a 50 Mhz crystal is osc/ISR_count
    ; percent error is (ISR_real-ISR_freq)*100)/ISR_freq
     
    ISR_count equ ((osc*10/ISR_freq)+5)/10
    ISR_real equ (osc/ISR_count)
     
    ; calculate the error to .1% resolution
     
    ; Real frequency is too high
    IF  (ISR_real) > (ISR_freq)
    ISR_Error  equ ((ISR_real-ISR_freq)*1000)/ISR_freq
    error P1W 'ISR Frequency is: ', ISR_real, ' Hz, high by',ISR_Error, ' %'
    ELSE
    ; Real frequency is too low
    ISR_Error  equ ((ISR_freq-ISR_real)*1000)/ISR_freq
    error P1W 'ISR Frequency is: ', ISR_real, ' Hz, low by .',ISR_Error, ' %'
    ENDIF
     
    ; not used in this example
    Half_ms_count equ osc*5/ISR_count/10000
     
    ; timer period in microseconds
     
    TIMER_INCREMENT equ (1_000_000*Half_ms_count/(ISR_real/10)+5)/10
     
    error P1W 'Timer period: ',TIMER_INCREMENT,' microseconds.'
     
    ;===============================================================================
    ; PIN ASSIGNMENTS
    ;===============================================================================
    ;
    ;                   +------v------+
    ;               1 --| Vss   /MCLR |-- 28
    ;               2 --| RTCC   OSC1 |-- 27
    ;               3 --| Vdd    OSC2 |-- 26
    ;               4 --| Vdd     RC7 |-- 25   PD7
    ;               5 --| N/C     RC6 |-- 24   PD6
    ;               6 --| RA0     RC5 |-- 23   PD5
    ;               7 --| RA1     RC4 |-- 22   PD4
    ;               8 --| RA2     RC3 |-- 21   PD3
    ;               9 --| RB3     RC2 |-- 20   PD2
    ;MFM_input_pin 10 --| RB0     RC1 |-- 19   PD1
    ;              11 --| RB1     RC0 |-- 18   PD0
    ;              12 --| RB2     RB7 |-- 17   PRNT_ATTN
    ;              13 --| RB3     RB6 |-- 16   PDBUS_OE 
    ;              14 --| RB4     RB5 |-- 15   DEBUG_OP
    ;                   +-------------+
    ;                     Ubicom SX28
    ;                     DIP package
    ;==============================================================================
    ;  I/O PORTS & RELATED CONSTANTS
    ;==============================================================================
     
    MFM_IN_PIN   equ rb.0  ; Input from Disk Drive
    DEBUG_OP     equ rb.5  ; output for timing debug
    PDBUS_OE     equ rb.6  ; Printer data bus Output Enable
    PRNT_ATTN    equ rb.7  ; Printer Attention line
    
    PDBUS        equ rc
     
    A_TRIS       equ %00000000 ; ra all pins output so no troubles
    A_INIT       equ %00000000 ; init to 0
    A_PLP        equ %00000000 ; disable pullups a all pins are outputs
    A_LVL        equ %00000000 ; CMOS input levels
     
    B_TRIS       equ 1 << .PDBUS_OE + 1 << . MFM_IN_PIN ; set up the inputs
    B_INIT       equ 1 << .PRNT_ATTN     ; attention line initially high, all else low
                                         ; enable pullups on  b inputs and data outputs
    B_PLP        equ 1 << .PDBUS_OE + 1 << . MFM_IN_PIN 
    B_WKED       equ %11111111           ; all pins set to detect falling edges
    B_WKEN       equ ~1 << .MFM_IN_PIN   ; disable wake up on pin except MFM input
    B_SCHMIDT    equ %00000000           ; all set to schmidt trigger
    B_LVL        equ %00000000           ; CMOS input levels
     
                                         ; default port c to all output except the
                                         ; receive data input
    C_TRIS       equ %11111111           ; all pins on bus input for now
    C_INIT       equ %00000000           ; all outputs low to start
    C_PLP        equ %00000000           ; enable pullups on all c pins
    C_SCHMIDT    equ %00000000           ; all set to schmidt trigger
    C_LVL        equ %00000000           ; CMOS input levels
    
    ;==============================================================================
    ;  MEMORY BANKS
    ;==============================================================================
    GLOBAL_MEM equ $08  ;
    BANK_0     equ $10  ; 
    BANK_1     equ $30  ; 
    BANK_2     equ $50  ; 
    BANK_3     equ $70  ; 
    BANK_4     equ $90  ; 
    BANK_5     equ $b0  ; 
    BANK_6     equ $d0  ; 
    BANK_7     equ $f0  ; 
    ;==============================================================================
    ;  BANKED MEMORY
    ;==============================================================================
    ISR_BANK equ BANK_0  ; used to hold whatever
    ;==============================================================================
    ;  GLOBAL MEMORY
    ;==============================================================================
           org GLOBAL_MEM           ; start of global register space
    GLOBAL_MEM_mode        ds 1   ; temp to keep track of mode register in the ISR
    GLOBAL_MEM_shifter     ds 1   ; stores incomming data from the Disk
    GLOBAL_MEM_bitcounter  ds 1   ; bit counter for receiving bits
    GLOBAL_MEM_ISR_temp    ds 1   ; temporary used by the ISR only
    ;==============================================================================
    ;  BANKED MEMORY
    ;==============================================================================
    ; Interrupt Routine pointers and data
    ;------------------------------------------------------------------------------
           org ISR_BANK
    ;------------------------------------------------------------------------------
    
    ;==============================================================================
    ;------------------------------------------------------------------------------
    ;  CODE MEMORY ORGANIZATION
    ;------------------------------------------------------------------------------
    ;==============================================================================
    PAGE_0         equ $000
    PAGE_1         equ $200
    PAGE_2         equ $400
    PAGE_3         equ $600
    ISR_PAGE       equ PAGE_0 ; ISR and initialization
    MAIN_PAGE      equ PAGE_1 ; State Machines
    NA1            equ PAGE_2 ; 
    NA2            equ PAGE_3 ; 
    ;==============================================================================
    ;  WATCH EXPRESSIONS
    ;==============================================================================
    ;==============================================================================
    ;  INTERRUPT SERVICE ROUTINE
    ;==============================================================================
    ;===============================================================================
      org ISR_PAGE
    ;===============================================================================
    ISR         setb  DEBUG_OP               ; set a bit to scope so we can see what happens
                clr   RTCC                   ; reset the RTCC in case it was a pin interrupt
                mov   GLOBAL_MEM_mode,m      ; save the mode
                mov   m,#WKPND               ; set to test our bit
                mov   !RB,#0x00              ; get the wake pending bit, into w
                not   w                      ; invert the bit so we match the original circuit
                mov   GLOBAL_MEM_ISR_temp,w  ; use a global for tmp so no bank junk
                rr    GLOBAL_MEM_ISR_temp    ; rr to get our transition bit into the carry
                rr    GLOBAL_MEM_shifter     ; from the schematic, the data comes in MSbit first
                djnz  GLOBAL_MEM_bitcounter,:exit_isr
                mov   GLOBAL_MEM_bitcounter,#8 ; reset bit counter
                mov   PDBUS,GLOBAL_MEM_shifter ; output new data to the data bus
    :exit_isr   mov   m,GLOBAL_MEM_mode        ; restore the mode
                mov   w,#-ISR_count
                CLRB  DEBUG_OP                 ; clear the bit so we see how long the ISR takes
                retiw                          ; return from interrupt and adjust the rtcc
    
    ;==============================================================================
    ; set up port direction and data registers, initialize the I/O
    init_io  mov m,#WKED    ; b edged detection
               mov   rb,  #B_WKED         ; 
               mov   m,   #WKPND          ; clear any wakeup pending bits
               clr   w                    ; so we don't fire the interrupt immediately
               mov   !rb,w                ; clear any wake up pending bits
               mov   m,   #WKEN           ; wakup on b transition
               mov   !rb, #B_WKEN   
    
               mov   m,   #PLP            ; Set the pullup values
               mov   !ra, #A_PLP
               mov   !rb, #B_PLP
               mov   !rc, #C_PLP
     
               mov   m,   #LVL            ; set the input levels TTL or CMOS
               mov   !ra, #A_LVL 
               mov   !rb, #B_LVL
               mov   !rc, #C_LVL
     
               mov   m,   #ST             ; set schmidt trigger inputs
               mov   !rb, #B_SCHMIDT
               mov   !rc, #C_SCHMIDT
               mov   ra,  #A_INIT
               mov   rb,  #B_INIT
               mov   rc,  #C_INIT
     
               mov   m,   #TRIS           ; Force mode to TRIS
               mov   !ra, #A_TRIS
               mov   !rb, #B_TRIS
               mov   !rc, #C_TRIS
               ret
    ;------------------------------------------------------------------------------
    ;==============================================================================
    ; initialize any variables used by the virtual peripherals
    ; i.e. the registers used to receive and transmit Serial data
    init_vp                                ; clear all general memory and global registers
            clr   fsr                      ; only clear the registers once
            setb  fsr.3                    ; forces skipping the i/o registers
    :gloop  clr   ind                      ; clear reg indexed by fsr
            inc   fsr
            sb    fsr.4
            jmp   :gloop                   ; loop until fsr becomes $10
    :bloop  setb  fsr.4
            clr   ind                      ; clear reg indexed by fsr
            ijnz  fsr, :bloop              ; loop until fsr becomes zero
            mov   GLOBAL_MEM_bitcounter, #8
            mov ! option,#OPTIONSETUP      ; start the ball rolling
            ret
    ;==============================================================================
    ;  Reset Location must be in Page 0
    ;==============================================================================
    Main  call   init_io  ; initialize the IO bits and state
          call   init_vp  ; initialize the RAM for all the VPs
      
    :forever
          clr   !WDT      ; whack the watchdog timer
          mov    m,#TRIS  ; set to control the output port to the printer
                          ; we don't really need to do this in the loop
                          ; because the ISR saves and restores it
          mov   w,#C_TRIS ; assume we want to tristate the output port
          sb    PDBUS_OE  ; if they pull it low, enable the PDBUS outout
          clr   w         ; enable the outputs
          mov   !PDBUS,w  ; 
      
          movb  PRNT_ATTN, GLOBAL_MEM_bitcounter.3 ; copy 3rd bit of counter
                                                   ; to the attention pin
                                                   ; will be high when we start
                                                   ; go low while shifting
                                                   ; and high again
                                                   ; for at least 2 microseconds
                                                   ; after we load data
          jmp  :forever
    ;-----------------------------------------------------------------
          END
    ;-----------------------------------------------------------------
    
    



    Post Edited (Michael Chadwick) : 3/14/2005 8:12:10 PM GMT
  • Michael ChadwickMichael Chadwick Posts: 80
    edited 2005-03-14 07:27
    You will likely have to adjust the ISR frequency or redefine it in terms of time. I think you really want to set the time out to a little longer than 2 microseconds, so that if you get two consecutive pulses, you grab the first, timeout to get the inbetween bit, and then have the next transition hit before the ISR timeout. So a little longer than half a bit time makes sense, I think, so it can always sync to the next pulse.
  • Keith MKeith M Posts: 102
    edited 2005-03-14 15:39
    Michael C said...
    You will likely have to adjust the ISR frequency or redefine it in terms of time. I think you really want to set the time out to a little longer than 2 microseconds, so that if you get two consecutive pulses, you grab the first, timeout to get the inbetween bit, and then have the next transition hit before the ISR timeout. So a little longer than half a bit time makes sense, I think, so it can always sync to the next pulse.
    Right.· I was coming up with something like 2.25 microseconds or so.· 2.5 was taking me too close to the far edge of some of the 8us cells I sampled -- the one I pictured was 7.6us.· I didn't want to sample at 7.5 if it was truly just 7.6.· 2.25 puts me at 2.25, 4.50, and 6.75.· The math takes me to 113 I think, I rounded to 115.

    I've made several attempts in SX/B writing the code with a couple different approaches.· None of them have panned out.· I'm sure I'm dealing with sync problems at this point --- I have to play with this stuff more before it starts to get intuitive...· I guarantee my problem is I'm not handling the RTCC correctly.

    I'll take a good look at your code.

    Thanks to everyone who replied.

    Keith
    ·
  • Michael ChadwickMichael Chadwick Posts: 80
    edited 2005-03-14 20:31
    Hi Keith,

    Here is a debugging trick you might already be using. Set an output bit at the start of the ISR and clear it at the end. Assuming your scope has dual trace, you can look at when the ISR happens in relation to the incomming data, and see how long the ISR takes by the length of the pulse.

    I've edited the code I posted to show that.

    If you have more than 2 channels, or if your scope has an external trigger, you could sync on the attention line to the PC and see where the end of the byte is and when the PC is supposed to be transfering it. That would sync you to the start of the next byte, so you could see what should be coming into the shifter, as well as if the attention line is getting set every 8 bits.

    Another variation would be to copy the state of the WKPND bit to the output bit, so you can see whether the ISR is interrpreting the data as a 0 or a 1.

    With a scope and an output bit, you can get some good visibility into what your code is doing relative to the data.

    Mike
  • Keith MKeith M Posts: 102
    edited 2005-03-15 15:07
    Thanks for the tip. Yeah, setting the ISR to trigger on at entry, and off at exit was a good idea I had not thought of. I finally got my timing in order, which is very solid now. So just when you would expect actual results, the code that has worked since day one breaks. Figure that out.

    <vent> You know, I've been programming(on the side, not for a living) half-seriously for probably about 15 years. Nothing irks me more than to have something very very simple NOT work. It's not the COMPLICATED things I get mad about not working -- I expect to have problems and to spend lots of troubleshooting time on HARD problems. But the easy stuff, that's just supposed to work on its face, that's what I get mad about not working </vent>

    I don't particularly like my current routines anyways. I'm going to shift more of the programming out of the ISR and more into the main --- which I guess is a good design goal. Keep the ISR as short as possible.

    Keith
  • Michael ChadwickMichael Chadwick Posts: 80
    edited 2005-03-16 04:45
    Hey man, That's par for the course isn't it? "But I didn't touch that part of the code!!" Then there are the bugs that disappear when you put in output statements to debug them. The Heisenbug. Goes away when you try to observe it.

    My most memorable bug was in my Z80 assembler days, working on the program for a piece of test equipment, a scanning optical densitometer. Used to measure color test targets on printing.

    I had coded some new scan routines to do automatic color bar recognition, that seemed to be working pretty well. Finished them up on a Monday. The gizmo was going to be shipped on Tuesday, so it all looked good. Everything tested out OK.

    On Tuesday morning the head of the service department, who was going to do the installation, ran through a test of the unit's function, part of which was to test the scanning on the customer's color bar. Didn't work. Bombed most convincingly.

    What the *&#%? "It worked fine yesterday!"

    I scratched my head a bit thinking about the problem and a light bulb went off. The scanner had a real time clock that displayed the date and time on a CRT as part of the instrument's display. I reset the date to Monday.

    It worked just fine. Oooops.

    In my scanning code, I had re-used the memory locations used by the clock output. Perfectly legal, and sometimes a must to re-use temp ram like that, which was always in short supply. (1984 ish, ram wasn't cheap.)

    But I had forgotten to *clear* it first. Or at least a particular byte that I used to hold flags indicating the state of the scan.

    So the program would work fine, except on Tuesdays and Thursdays. Fortunately I found it pretty quickly, and the service guy was able to load the unit into the company van and deliver it on time.

    But I won't forget that one.

    As you hunt your bugs, keep in mind that the processor (usually) is doing *exactly* what you told it to do.

    Mike
  • Keith MKeith M Posts: 102
    edited 2005-03-17 15:53
    Heh.· I've seen those densitometers before. And colorimeters.· Who are the big ones? ColorVision, MonacoSys / Xrite, Pantone, a couple others?· For awhile I was getting very deep into printer profiling my home color inkjet.· Color is a real pain in the butt.· I should say MATCHING color is a big pain in the butt.· And the different types / temperatures of light, etc.· I tried everything under the sun to improve the default printer profiles without spending $1000.· Basically coming up with a good workflow from digital camera to paper.· It's tough to do correctly.· I buy paper now that comes with custom printer profiles designed for my printer/inks.· I was even going to paint my office at home a neutral gray and replace the light bulbs.· But then common sense returned!

    lol.gif

    This is entirely OT BUT Pantone has this really cute handheld spectro-colorimeter.· Under $250 too!

    http://www.pantone.com/products/products.asp?idSubArea=0&idArea=2&showNav=94&idProduct=373

    I've contemplating buying one but the reports on it aren't very favorable --- at least not in the serious context....

    Keith



    Post Edited (Keith M) : 3/17/2005 4:15:39 PM GMT
Sign In or Register to comment.