if/else Assembly input/output pins
in Propeller 1
Hello,
I am having an issue with the assembly code attached,
I have two input pins - Pin 24 and pin 26, if low I call an assembly function to build a signal, if High I call a different signal
I use xor and if_z or If_nz to determine the jump, the problem is it only works sometimes, so odds are it is incorrect,
what is weird is that if I swap the if_z to if_nz and vice versa, I get it to work correctly for awhile, then it reverses. so i think the tests are wrong or giving me the wrong flag.
I have attached the code. I would like a different test method, basically a If/else test of a input pin and output to an output pin, for two different input pins and two different output pins.
thanks in advance.
regards
Jeff
I am having an issue with the assembly code attached,
I have two input pins - Pin 24 and pin 26, if low I call an assembly function to build a signal, if High I call a different signal
I use xor and if_z or If_nz to determine the jump, the problem is it only works sometimes, so odds are it is incorrect,
what is weird is that if I swap the if_z to if_nz and vice versa, I get it to work correctly for awhile, then it reverses. so i think the tests are wrong or giving me the wrong flag.
I have attached the code. I would like a different test method, basically a If/else test of a input pin and output to an output pin, for two different input pins and two different output pins.
thanks in advance.
regards
Jeff
CON
_CLKMODE = xtal1 + pll16x
_XINFREQ = 6_200_000
MY_PIN_24 = 24
PUB main
cognew(@lfs_heater, 0) ' Start a Cog with our assembly routine, no stack
' is required since PASM requires we explicitly
' assign and use memory locations within the Cog/Hub
DAT
org 0
LFS_heater mov dira, Both_P2_P5_output' Pin24 ' Set our Pin to an output
mov outa,Both_P2_P5_low
'mov dira, Pin26
rdlong Delay, #0
:keep_checking mov temp1, ina 'Get the current inputs
and temp1, Input_P24_P26_Mask 'Mask the inputs that you care about
' check ping 24
xor temp1, Just_input_pin24 wz,nr 'Check if just input 24 is high
if_z jmpret :On_Signal_Base_ret,#:On_Signal_Base_int
xor temp1, Just_input_pin24 wz,nr 'Check if just input 24 is low
'
if_nz jmpret:Off_Signal_Base_ret,#:Off_Signal_Base_int
' check ping 26
xor temp1, Just_input_pin26 wz,nr 'Check if just input 26 is high
if_z jmpret :On_Signal_Hopper_ret,#:On_Signal_Hopper_int
xor temp1, Just_input_pin26 wz,nr 'Check if just input 2 is low
if_nz jmpret :Off_Signal_Hopper_ret,#:Off_Signal_Hopper_int
jmp#:keep_checking
:Off_Signal_Base_int
mov Time, cnt ' Prime our timer with the current value of the system counter
add Time, Period200us ' Add a minimum delay ( more on this below )
:Off_Signal_Base waitcnt Time, #14 ' Start waiting
xor outa, Pin2
waitcnt Time,#12
xor outa, Pin2
waitcnt Time,#24
xor outa, Pin2
waitcnt Time,#24
xor outa, Pin2
waitcnt Time,#49
xor outa, Pin2
waitcnt Time, #49
xor outa, Pin2
waitcnt Time, #24
xor outa, Pin2
waitcnt Time, #24
xor outa, Pin2
:Off_Signal_Base_ret jmp# 0
:Off_Signal_Hopper_int
mov Time, cnt ' Prime our timer with the current value of the system counter
add Time, Period200us ' Add a minimum delay ( more on this below )
:Off_Signal_Hopper waitcnt Time, #14 ' Start waiting
xor outa, Pin5
waitcnt Time,#12
xor outa, Pin5
waitcnt Time,#24
xor outa, Pin5
waitcnt Time,#24
xor outa, Pin5
waitcnt Time,#49
xor outa, Pin5
waitcnt Time, #49
xor outa, Pin5
waitcnt Time, #24
xor outa, Pin5
waitcnt Time, #24
xor outa, Pin5
:Off_Signal_Hopper_ret jmp# 0
:On_Signal_Base_int
mov Time, cnt ' Prime our timer with the current value of the system counter
add Time, Period200us ' Add a minimum delay ( more on this below )
:On_Signal_Base waitcnt Time, #10 ' Start waiting
xor outa, Pin2
waitcnt Time,#40
xor outa, Pin2
waitcnt Time,#75
xor outa, Pin2
waitcnt Time,#50
xor outa, Pin2
waitcnt Time,#25
xor outa, Pin2
waitcnt Time,#25
xor outa, Pin2
:On_Signal_Base_ret jmp# 0
:On_Signal_Hopper_int mov Time, cnt ' Prime our timer with the current value of the system counter
add Time, Period200us ' Add a minimum delay ( more on this below )
:On_Signal_Hopper waitcnt Time, #10 ' Start waiting
xor outa, Pin5
waitcnt Time,#40
xor outa, Pin5
waitcnt Time,#75
xor outa, Pin5
waitcnt Time,#50
xor outa, Pin5
waitcnt Time,#25
xor outa, Pin5
waitcnt Time,#25
xor outa, Pin5
:On_Signal_Hopper_ret jmp# 0
Pin2 long |< 2 ' Encde PIN to a bit mask
Pin5 long |< 5 ' Encde PIN to a bit mask
Input_5 long |< 5
Period200us long 20000 ' 100 us
temp long
Input_3_5_Mask long %00000000_0010_1000
Input_2_5_Mask long %00000000_0010_0100
Just_input_pin5 long %00000000_0010_0000
Just_input_pin2 long %00000000_0000_0100
Just_input_pin24 long %00000001_00000000_00000000_00000000
Just_input_pin24_L long %11111110_11111111_11111111_11111111
Just_input_pin26 long %00000100_00000000_00000000_00000000
Just_input_pin26_L long %11111011_11111111_11111111_11111111
Just_input_pin3 long %00000000_0000_1000
Input_P24_P26_Mask long %00000101_00000000_00000000_00000000
Input_P24_P26_Mask_L long %11111010_11111111_11111111_11111111
Both_P2_P5_output long %00000000_00000000_00000000_00100100
Both_P2_P5_low long %00000000_00000000_00000000_00000000
temp1 long 0
Delay res 1
Time res 1
FIT 496

Comments
If you ever want help in some PASM logic, one quick and dirty way to check it might be to write the code in Spin and then translate it to PASM using the Spin Converter program. Spin Converter is still very alpha, but simple if/then/else control logic and pin manipulation should work fine.
There are specific instances where you want to use the JMPRET instruction (i.e., coroutines), but for normal subroutine call/ret, you should use those assembler mnemonics, as follows:
Note that there is no PASM 'call'; the assembler will replace "call #Subroutine" with "jmpret #Subroutine_ret, #Subroutine", and replace "ret" with "jmp #0" (during runtime, the "#0" will be replaced with "#(Main_code+1)" by the call (jmpret) instruction). Note also that you never need to refer to "_ret" in the caller code; it is hardcoded into the assembler.
Edit: I used a colon at the end of the labels, which is not required in SPIN PASM, and normally not used, although it also works. I use it because I program in GCC PASM, and I've noticed that if I want to indent the label (sometimes I do this to make nested loops more clear), it will only work if there is a colon appended to the label.
:keep_checking test PIN24, ina wc 'Get the current inputs if_c call #On_Signal_Base_int if_nc call #Off_Signal_Base_int test Pin26, ina wc if_c call #On_Signal_Hopper_int if_nc call #Off_Signal_Hopper_int jmp #:keep_checking Off_Signal_Base_int mov Time, cnt add Time, Period200us Off_Signal_Base waitcnt Time, #14 xor outa, Pin2 waitcnt Time,#12 xor outa, Pin2 waitcnt Time,#24 xor outa, Pin2 waitcnt Time,#24 xor outa, Pin2 waitcnt Time,#49 xor outa, Pin2 waitcnt Time, #49 xor outa, Pin2 waitcnt Time, #24 xor outa, Pin2 waitcnt Time, #24 xor outa, Pin2 Off_Signal_Base_int_ret Off_Signal_Base_ret ret ... Pin2 long 1<<2 Pin24 long 1<<24 Pin26 long 1<<26Andy
thanks for the info, I modified it to this:
test Just_input_pin24, ina wz ' test for pin 24 if_z jmpret :Off_Signal_Base_ret,#:Off_Signal_Base_int if_nz jmpret :On_Signal_Base_ret,#:On_Signal_Base_int ' ' test Just_input_pin26, ina wz 'test for pin 26 if_z jmpret :Off_Signal_Hopper_ret,#:Off_Signal_Hopper_int if_nz jmpret :On_Signal_Hopper_ret,#:On_Signal_Hopper_intand it seems to work,
regards
Jeff
This is the final working version of the code:
CON _CLKMODE = xtal1 + pll16x _XINFREQ = 6_200_000 PUB main cognew(@lfs_heater, 0) ' Start a Cog with our assembly routine, no stack ' is required since PASM requires we explicitly ' assign and use memory locations within the Cog/Hub DAT org 0 LFS_heater mov dira, Both_P2_P5_output' Pin24 ' Set our Pin to an output mov outa,Both_P2_P5_low rdlong Delay, #0 :keep_checking test Just_input_pin24,ina wz ' test for pin 24 if_z call #Off_Signal_Base if_nz call #On_Signal_Base ' ' test Just_input_pin26, ina wz 'test for pin 26 if_z call #Off_Signal_Hopper if_nz call #On_Signal_Hopper jmp#:keep_checking Off_Signal_Base mov Time, cnt ' Prime our timer with the current value of the system counter add Time, Period200us ' Add a minimum delay ( more on this below ) waitcnt Time, #14 ' Start waiting xor outa, Pin2 waitcnt Time,#12 xor outa, Pin2 waitcnt Time,#24 xor outa, Pin2 waitcnt Time,#24 xor outa, Pin2 waitcnt Time,#49 xor outa, Pin2 waitcnt Time, #49 xor outa, Pin2 waitcnt Time, #24 xor outa, Pin2 waitcnt Time, #24 xor outa, Pin2 Off_Signal_Base_ret ret Off_Signal_Hopper mov Time, cnt ' Prime our timer with the current value of the system counter add Time, Period200us ' Add a minimum delay ( more on this below ) waitcnt Time, #14 ' Start waiting xor outa, Pin5 waitcnt Time,#12 xor outa, Pin5 waitcnt Time,#24 xor outa, Pin5 waitcnt Time,#24 xor outa, Pin5 waitcnt Time,#49 xor outa, Pin5 waitcnt Time, #49 xor outa, Pin5 waitcnt Time, #24 xor outa, Pin5 waitcnt Time, #24 xor outa, Pin5 Off_Signal_Hopper_ret ret On_Signal_Base mov Time, cnt ' Prime our timer with the current value of the system counter add Time, Period200us ' Add a minimum delay ( more on this below ) waitcnt Time, #10 ' Start waiting xor outa, Pin2 waitcnt Time,#40 xor outa, Pin2 waitcnt Time,#75 xor outa, Pin2 waitcnt Time,#50 xor outa, Pin2 waitcnt Time,#25 xor outa, Pin2 waitcnt Time,#25 xor outa, Pin2 On_Signal_Base_ret ret On_Signal_Hopper mov Time, cnt ' Prime our timer with the current value of the system counter add Time, Period200us ' Add a minimum delay ( more on this below ) waitcnt Time, #10 ' Start waiting xor outa, Pin5 waitcnt Time,#40 xor outa, Pin5 waitcnt Time,#75 xor outa, Pin5 waitcnt Time,#50 xor outa, Pin5 waitcnt Time,#25 xor outa, Pin5 waitcnt Time,#25 xor outa, Pin5 On_Signal_Hopper_ret ret Pin2 long |< 2 ' Encde PIN to a bit mask Pin5 long |< 5 ' Encde PIN to a bit mask Period200us long 20000 ' 200 us Input_2_5_Mask long %00000000_0010_0100 Just_input_pin24 long %00000001_00000000_00000000_00000000 Just_input_pin26 long %00000100_00000000_00000000_00000000 Both_P2_P5_output long %00000000_00000000_00000000_00100100 Both_P2_P5_low long %00000000_00000000_00000000_00000000 temp1 long 0 Delay res 1 Time res 1 FIT 496Here's another way to test, keeping more in line with the comments of just one or the other:
LFS_heater or dira,p2_p5_mask :loop mov temp1,ina test temp1,p24_p26_mask wc ' C is cleared if both low or both high if_nc jmp #:loop test temp1,p24_mask wc ' C is set if P24 high, P26 low if_c jmp #:base_on_hopper_off :base_off_hopper_on call #Off_Signal_Base call #On_Signal_Hopper jmp #:loop :base_on_hopper_off call #On_Signal_Base call #Off_Signal_Hopper jmp #:loop