; Sun 01-13-0212:41:34 ; rev 2 of the code. ; this version adds code to support the extra opto-iso, so that the ; PIC can signal the PC that an EStop has occurred ; ; Tue 01-22-0219:35:25 ; rev 3 ; changes how the relays are handled at reset. Rev 2 may cause the ; relays to glitch device pic16c55,xt_osc,wdt_off,protect_off reset start ;----------------------------------------------------------------------------- ; equates ;----------------------------------------------------------------------------- rambase equ 8 Xstop equ RC.0 Ystop equ RC.1 Zstop equ RC.2 Astop equ RC.3 Allstop equ RC.4 Estop equ RC.5 Xout equ RB.0 Yout equ RB.1 Zout equ RB.2 Aout equ RB.3 Xerr equ RB.7 Yerr equ RB.6 Zerr equ RB.5 Aerr equ RB.4 XerrIn equ RA.0 YerrIn equ RA.1 ZerrIn equ RA.2 AerrIn equ RA.3 ;----------------------------------------------------------------------------- ; ram ;----------------------------------------------------------------------------- org rambase temp ds 1 temp1 ds 1 Gtemp ds 1 Gtemp1 ds 1 RAtemp ds 1 RBtemp ds 1 disable_flag ds 1 loop_counter ds 1 power_up ds 1 ;----------------------------------------------------------------------------- ; more equates ;----------------------------------------------------------------------------- DisableX_bit equ disable_flag.0 DisableY_bit equ disable_flag.1 DisableZ_bit equ disable_flag.2 DisableA_bit equ disable_flag.3 DisableAll_bit equ disable_flag.4 DisableE_bit equ disable_flag.5 power_up_flag equ power_up.0 ;----------------------------------------------------------------------------- ; reset vector ;----------------------------------------------------------------------------- org 0 goto start ;----------------------------------------------------------------------------- ; reset routine ;----------------------------------------------------------------------------- initial_init ; hold Geckos in Stop mov RA,#0 ; put the port into output mode mov !RA,#0 ; wait around a bit .. wait longer if this is initial power up call sdelay jnb power_up_flag, skipit call _1secdelay ; extra delay at powerup only skipit clr power_up ; we never need to do this again ; RAtemp will be used to keep track of how we'll program RA -> Geckos ; RBtemp1 will keep track of the relays and the LEDS -> RB mov RAtemp,#0 ; set up the variable mov RBtemp,#11110000b mov RB,RBtemp ; turn on LEDs, leave relays off mov disable_flag,RC ; read the switches and store in ; disable_flag variable ; anything to check at all ? jnb DisableAll_bit, Skip_All jb DisableE_bit, Skip_All ; check switch by switch ; if bit not set, channel is disabled, so skip over the block of code ; that turns the relay on and the LED off. jnb DisableX_bit, skip_Xrelay ; here because we need to do something or RBtemp, #1 ; turn on LED bit and RBtemp, #01111111b ; mask off the LED bit mov RB, RBtemp ; turn on the relay, turn off the LED add RAtemp,#1 ; save Gecko status call rebound ; we have just turned a relay on, ; so wait around a bit, to give the ; power supply a chance to recharge skip_Xrelay jnb DisableY_bit, skip_Yrelay or RBtemp, #10b and RBtemp, #10111111b mov RB, RBtemp add RAtemp,#10b call rebound skip_Yrelay jnb DisableZ_bit, skip_Zrelay or RBtemp, #100b and RBtemp, #11011111b mov RB, RBtemp add RAtemp,#100b call rebound skip_Zrelay jnb DisableA_bit, skip_Arelay or RBtemp, #1000b and RBtemp, #11101111b mov RB, RBtemp add RAtemp,#1000b call rebound skip_Arelay ; relays are on as appropriate, LEDS also, so time to wait around for 5 seconds ; put all of the Geckos into Reset mov RA, #0ffh ; we want to blink the LEDS while in RESET. A bit tricky because while ; we want to blink the LEDS, we don't want to mess with the current state ; of the relays mov loop_counter, #25 blink_start mov temp, RBtemp or temp, #0f0h mov RB,temp call sdelay mov temp, RBtemp and temp, #0fh mov RB,temp call sdelay djnz loop_counter, blink_start ; should be reset by now, so put the LEDs back to where they belong mov RB,RBtemp ; now time to enable the Geckos mov RA,#0 mov !RA,RAtemp ; finally, release the EStop output to the PC mov RC,#00111111b ret Skip_All mov RA,#0 mov !RA,#0 ; leave Geckos in reset mov RB,#0F0h mov !RB,#0 ; LEDS on Relays off mov RC,#0ffh ; EStop true mov !RC,#00111111b ; inputs and 2 outputs ret ; --------------------------- ; some delay routines ; --------------------------- _1secdelay mov temp,#40 delayloop mov RTCC,#0 :wait jnb RTCC.7, :wait djnz temp, delayloop ret ; a short delay used to blink the LEDs at reset sdelay mov temp,#3 sdelayloop mov RTCC,#0 :wait jnb RTCC.7, :wait djnz temp, sdelayloop ret ; a short delay to make it easier for the power supply to turn on a number ; of relays rebound mov temp,#5 reboundloop mov RTCC,#0 :wait jnb RTCC.7, :wait djnz temp, reboundloop ret ; a very short delay to debounce a switch debounce mov RTCC,#0 :wait jnb RTCC.2, :wait ret ;----------------------------------------------------------------------------- ; ID string goes here ; retw 'G','e','c','k','o',' ','3','x','0',' ' retw 'R','e','s','e','t',' ','C','o','n','t','r','o','l','l','e','r' retw 'F','r','i',' ',' ','0','1','-','2','5','-','0','2' ;----------------------------------------------------------------------------- ; program entry point ;----------------------------------------------------------------------------- org 100h ;----------------------------------------------------------------------------- start clrwdt clrb PA0 clrb PA1 movlw 00000111b ;Bit 0,1,2 = Prescaler divider = 256 ;Bit 3 = Prescaler assign: 0 for timer 0, 1 for WDT ;Bit 4 = RTCC edge: 0 = low to high ;Bit 5 = RTCC source: 0 = internal option mov RA,#0ffh mov RC,#0ffh mov RB,#0 ; things are turned on when bit is high mov !RA,#0ffh ; inputs mov !RB,#0 ; outputs mov !RC,#00111111b ; inputs and 2 outputs mov disable_flag,#0fh mov power_up,#0ffh ; ---------------------------------------------------------------------- real_start call initial_init ; pulls Geckos into reset for 5 seconds mov disable_flag,#0fh ; Gecko Err/Res inputs now in tristate ; all channels enabled ; Gecko Err/Res should be outputting a logic 1 loop_start ; first, check the critical inputs jnb Estop, check_allstop ; switch seems to be pressed, but should double check call debounce ; wait a bit jnb Estop, check_allstop ; still true ? jmp do_Estop ; read external input check_allstop jb AllStop, check_Xstop call debounce jb AllStop, check_Xstop ; still true ? jmp do_Allstop ; Next, check to see if we need to disable any of the channels, based ; upon the state of the switches. ( later, we'll see if we need to ; re-enable a channel ) ; checking of the switches is tricky ; for purposes of explanation, to disable a channel, a switch is said to ; be "down" , since down is usually off. ; if we find a switch down, we need to turn off the relay ; AND turn off the Gecko. However, we may need to turn off ; several Geckos in turn. To be sure that turning off a ; Gecko leaves all the other Geckos in the same state, on or off, ; we need to set a flag .. the Disable_flag check_Xstop jb Xstop, check_Ystop call debounce jb Xstop, check_Ystop ; double check clrb Xout ; turn off the relay setb Xerr clrb DisableX_bit mov RA,Disable_flag mov !RA,Disable_flag check_Ystop jb Ystop, check_Zstop call debounce jb Ystop, check_Zstop ; double check clrb Yout ; turn off the relay setb Yerr clrb DisableY_bit mov RA,Disable_flag mov !RA,Disable_flag check_Zstop jb Zstop, check_Astop call debounce jb Zstop, check_Astop ; double check clrb Zout ; turn off the relay setb Zerr clrb DisableZ_bit mov RA,Disable_flag mov !RA,Disable_flag check_Astop jb Astop, check_Xon call debounce jb Astop, check_Xon ; double check clrb Aout ; turn off the relay setb Aerr clrb DisableA_bit mov RA,Disable_flag mov !RA,Disable_flag ;-------------------------------------------------------------------------- ; now we get to see if any switches that WERE down are now up check_Xon ; should we even bother ? If the disable_bit is CLEARED, it means the ; the switch was down at one point. jb DisableX_bit, check_Yon call debounce jb DisableX_bit, check_Yon ; double check ; yup, we should bother. now, has it changed ? jnb Xstop, check_Yon ; switch is now up, so we need to reset the channel. we do that ; by resetting all the channels ; ; some may quibble about this .. resetting all the Geckos when a single ; switch goes back up, but the reasoning is this. ; ; 1. it would be very tricky to re-enable the channel with a 5 second ; logic 1 on the appropriate Gecko Err/Res pin without running the risk of ; missing an EStop input or a Gecko fault. Remember, this PIC has no ; interrupts ; ; 2. since it takes a channel 5 seconds to become active, there's no way ; to turn a channel on quickly anyway .. it must be planned for ; ; 3. I can't think of when this would be a problem. setb DisableX_bit clrb Xerr jmp real_start ; which initiates a ; power on reset check_Yon jb DisableY_bit, check_Zon call debounce jb DisableY_bit, check_Zon ; double check jnb Ystop, check_Zon setb DisableY_bit clrb Yerr jmp real_start check_Zon jb DisableZ_bit, check_Aon call debounce jb DisableZ_bit, check_Aon ; double check jnb Zstop, check_Aon setb DisableZ_bit clrb Zerr jmp real_start check_Aon jb DisableA_bit, check_Gecko call debounce jb DisableA_bit, check_Gecko ; double check jnb Astop, check_Gecko call debounce jnb Astop, loop_start setb DisableA_bit clrb Aerr jmp real_start ; --------------------------------------------------------------------------- check_Gecko mov Gtemp, RA ; read the port and Gtemp, #00001111b ; mask off the top of temp mov Gtemp1, Gtemp xor Gtemp1, disable_flag ; mask off any channels disabled by ; the switches jz loop_start ; a channel has faulted, so kill the other channels mov RA, #0 mov !RA, #0 ; turn off the lights ( for now ), turn off the relays mov RB, #0 mov !RB, #0 ; signal EStop to the PC mov RC,#0ffh ; blink the light to indicate the channel that faulted blink: ; check X channel jb Gtemp.0, :_Y ; bit was low, i.e. channel faulted, but was it turned low by the X ; disable switch ? jnb DisableX_bit, :_Y ; this channel faulted, so turn on LED setb Xerr :_Y jb Gtemp.1, :_Z jnb DisableY_bit, :_Z setb Yerr :_Z jb Gtemp.2, :_A jnb DisableZ_bit, :_A setb Zerr :_A jb Gtemp.3, blink1: jnb DisableA_bit, blink1: setb Aerr blink1: call sdelay ; just a short delay mov RB,#0 ; all LEDs off ; wait for the Allstop switch to be toggled ; first wait for it to be closed/down jnb Allstop, exit_waiting ; not down yet, so blink the leds call sdelay jmp blink: ; Allstop switch set exit_waiting ; turn on all the LEDs, leave the relays off mov RB, #0f0h mov !RB, #0 call debounce ; wait for it to be turned off :wait1 jnb Allstop, :wait1 ; switch is off, so reset everything jmp real_start ; --------------------------------------------------------------------------- ; when Estop goes true, stop everything do_Estop mov RA,#0 mov !RA,#0 ; put Geckos into reset mov !RB,#0 mov RB,#11110000b ; light on lights ; turn off relays mov RC,#0ffh ; let the PC know, if it ; doesn't already mov RB,#10000000b call sdelay mov RB,#1000000b call sdelay mov RB,#100000b call sdelay mov RB,#10000b call sdelay jb Estop,do_Estop ; wait around until EStop is fixed jmp real_start ; when Allstop goes true, stop everything do_Allstop mov RA,#0 mov !RA,#0 ; put Geckos into reset mov !RB,#0 mov RB,#11110000b ; light on lights ; turn off relays mov RC,#0ffh ; let the PC know call debounce jnb Allstop,do_Allstop ; wait around until EStop is fixed jmp real_start