Shop OBEX P1 Docs P2 Docs Learn Events
Problem writeing Numbers and pins in Assembly — Parallax Forums

Problem writeing Numbers and pins in Assembly

krazyideaskrazyideas Posts: 119
edited 2008-12-12 02:12 in Propeller 1
Hello
I don't know how to write this quite right.· I don't know how to write the 32 bit binary numbers in 9 bits of space for assmebly code.
I need to know how to write dira,·· and outa high low on desginated pins

This is what I have.
Thanks for any help


Dat
ReadFireTime1·········· COGID one
······················· mov dira, 12···················PROBLEM·· ·'Set output pin······················
······················· movi CTRA, %11111
:Relay1················ waitpeq 1, |< 9············PROBLEM·· ·'Set 0 mark on pin 10
······················· mov PHSA, 0···················· ············· 'Mark 0
······················· waitpeq 1, |< 0···············PROBLEM · ·'Window starts
······················· mov outa, [noparse][[/noparse]12]~~···········PROBLEM · ·'Relay pluse···
······················· mov WinStart1, PHSA········ ············· 'Mark counts to turn on···
······················· mov TurnOn1, WinStart1···· ············· 'Store counts to turn on in turnon
······················· waitpne 1, |< 0···············PROBLEM ·· 'Window ends
······················· mov outa [noparse][[/noparse]12]~···············PROBLEM· · 'Relay pluse···
······················· mov WinEnd1, PHSA························· 'Mark turn off····
······················· sub WinEnd1, WinStart1··················· 'Leangth of window
······················· mov TurnOff1, WinEnd1···················· 'Store Window Leangth
······················· jmp #:Relay1·································· 'Loop endlessly
·······················
WinStart····· Long··· 'Mark
WinEnd······· Long··· 'Mark
TurnOn1······ Long··· '# of cnt's to wait before turn on
TurnOff1····· Long··· '# of cnt's to Stay on before turn off
one·········· word
Dat



ExicuteFireTime1······· mov dira [noparse][[/noparse]12]~~·········PROBLEM·········· 'Set output pin

:FireingLoop1·········· WAITPEQ 1, |< 9··········PROBLEM
······················· mov syncdelay1, cnt······························· 'Set Zero
······················· add syncdealy1, TurnOn1························· 'Set wait till turn on
······················· waitcnt syncdelay1, TurnOff1··················· 'When cnt = syncdelay output High
······················· mov outa [noparse][[/noparse]12]~~················ PROBLEM
······················· waitcnt syncdelay1, DeadZ······················· 'When cnt = syncdelay output Low
······················· mov outa [noparse][[/noparse]12]~···················PROBLEM
······················· jmp #:FireingLoop1·································· 'Loop endlessly
syncdelay1···· Long

Post Edited (krazyideas) : 12/7/2008 12:17:24 AM GMT

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-07 00:17
    As you might suspect, you can't squeeze 32 bits into 9 bits of space. You can put the 32 bit value into its own location and the address of that location will fit into 9 bits like this:
            or           dira, pinMask           ' To make the I/O pin an output
            andn       dira, pinMask           ' To make the I/O pin an input
    
            or           outa, pinMask          ' To turn the I/O pin on
            andn       outa, pinMask          ' To turn the I/O pin off
    
            waitpeq   pinMask,pinMask      ' To wait for the I/O pin to be high
            waitpne   pinMask,pinMask      ' To wait for the I/O pin to be low
    
    pinMask  long        |< 26          ' A single one bit in the position for pin 26
    

    Post Edited (Mike Green) : 12/7/2008 12:23:05 AM GMT
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-07 00:21
    Thanks very much
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-07 00:34
    How do you specifi if the command outa , pinmask is High or Low??
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-07 00:51
    I should have said "To make the output pin high" instead of "To turn the I/O pin on" and "To make the output pin low" instead of "To turn the I/O pin off".
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-07 00:53
    Ok so Now these two progams should work now right.

    Sorry for not just attaching it my computer locks up it I try too

    Thanks for any thoughts



    Dat

    ReadFireTime1·····COGID one
    ······················· or·········· dira, DirOutPutPin············· 'Set output pin······················
    ······················· movi······· CTRA, %11111

    :Relay1··············waitpeq··· MarkerPin, MarkerPin········· 'Set 0 mark on pin 10
    ······················· mov········ PHSA, 0························· ·'Mark 0

    ······················· waitpeq··· WindowPin, WindowPin·········'Window starts
    ······················· or··········· outa, OutPutPin················ 'Relay pluse···
    ······················· mov········ WinStart1, PHSA··············· 'Mark counts to turn on···
    ······················· mov········ TurnOn1, WinStart1··········· 'Store counts to turn on in turnon

    ······················· waitpne··· WindowPin, WindowPin········'Window ends
    ······················· andn······· outa, OutPutPin················ 'Relay pluse···
    ······················· mov········ WinEnd1, PHSA················· 'Mark turn off····
    ······················· sub········· WinEnd1, WinStart1··········· 'Leangth of window
    ······················· mov········ TurnOff1, WinEnd1············· 'Store Window Leangth

    ······················· jmp #:Relay1···························· 'Loop endlessly
    ·······················
    WinStart····· Long··· 'Mark
    WinEnd······· Long··· 'Mark
    TurnOn1······ Long··· '# of cnt's to wait before turn on
    TurnOff1····· Long··· '# of cnt's to Stay on before turn off
    one··········· word

    DirOutPutPin· long····· |< 12
    MarkerPin····· long····· |< 9
    WindowPin···· long····· |< 0
    OutPutPin····· long····· |< 12





    Dat

    ExicuteFireTime1······· or····· dira, DirOut······················ 'Set output pin


    :FireingLoop1·······WAITPEQ Mark, Mark
    ······················· mov········ syncdelay1, cnt················· 'Set Zero
    ······················· add········ ·syncdealy1, TurnOn1·········· 'Set wait till turn on
    ······················· waitcnt···· syncdelay1, TurnOff1··········'When cnt = syncdelay output High
    ······················· or············ outa, OutPin
    ······················· waitcnt···· syncdelay1, 500··············· 'When cnt = syncdelay output Low
    ······················· andn········ outa, OutPin

    ······················· jmp #:FireingLoop1·························· 'Loop endlessly

    syncdelay1··· Long
    ·····

    DirOut······· long····· |< 12
    OutPin······· long····· |< 12
    Mark········· long····· |< 9

    Post Edited (krazyideas) : 12/7/2008 1:09:50 AM GMT
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-07 01:08
    Thanks Mike

    That helped tons
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-07 01:11
    one, WinStart, WinEnd, TurnOn1, TurnOff1, and syncdelay1 all will not work the way you expect. When you use word or long in a DAT block it first forces alignment of the next location to a word or long boundary, then allocates one word or long for each operand. If you don't provide a value, nothing is allocated, so WinStart, WinEnd, TurnOn1, TurnOff1, and on all are defined as the same location. syncdelay1 is defined as the same location as DirOut.

    "movi CTRA,%11111" needs to be "movi CTRA,#%11111".

    There are several other instructions that need to have the "#" added to their source field.

    "waitpeq 1,WindowPin" needs to be "waitpeq WindowPin,WindowPin".
    Similarly, "waitpne 1,WindowPin" needs to be "waitpne WindowPin,WindowPin"
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-07 01:20
    Thanks again Mike
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-07 05:40
    Hello Again.· Ok I think I have it this time.

    I think these two programs should work now. But I would like to hear what some of you guys that know what your doing have to say.

    Thanks for any comments



    Dat

    ReadFireTime1·····COGID····· one
    ······················· or··········· dira, DirOutPutPin1················· 'Set output pin······················
    ······················· movi······· ·CTRA, #%11111
    ·································································
    :Relay1··············waitpeq··· MarkerPin1, MarkerPin1··········· ·'Set 0 mark on pin 9
    ······················· mov········ PHSA, 0································ 'Mark 0

    ······················· waitpeq··· WindowPin1, WindowPin1········ 'Window starts
    ······················· or··········· outa, OutPutPin1··················· 'Relay pluse···
    ······················· mov········ WinStart1, PHSA··················· 'Mark counts to turn on···
    ······················· mov········ TurnOn1, WinStart1··············· 'Store counts to turn on in turnon

    ······················· waitpne··· WindowPin1, WindowPin1········ 'Window ends
    ······················· andn······· outa, OutPutPin1··················· 'Relay pluse···
    ······················· mov········ WinEnd1, PHSA····················· 'Mark turn off····
    ······················· sub········ ·WinEnd1, WinStart1··············· 'Leangth of window
    ······················· mov········ TurnOff1, WinEnd1················· 'Store Window Leangth

    ······················· jmp #:Relay1····································· ·'Loop endlessly
    ·······················
    WinStart1····· long····· 5·········· 'Mark
    WinEnd1······· long····· 5·········· 'Mark
    TurnOn1······· long····· 5·········· '# of cnt's to wait before turn on
    TurnOff1······ long····· 5··········· '# of cnt's to Stay on before turn off
    one············· word····· 1·········· 'CogID

    DirOutPutPin1· long····· |< 12······ 'Set out put pin
    MarkerPin1···· ·long····· |< 9········ 'Zero mark pin
    WindowPin1···· long····· |< 0······· 'Window mark pin
    OutPutPin1····· long····· |< 12······ 'Output pin



    Dat

    ExicuteFireTime1······· or··········· dira, DirOut1···················· 'Set output pin


    :FireingLoop1·········· WAITPEQ··· Mark1, Mark1
    ···························· mov········ ·syncdelay1, cnt··············· 'Set Zero
    ···························· add·········· syncdelay1, TurnOn1·········'Set wait till turn on
    ··························· waitcnt······ syncdelay1, TurnOff1········'When cnt = syncdelay output High
    ···························· or············ outa, OutPin1
    ··························· waitcnt······ syncdelay1, 500···············'When cnt = syncdelay output Low
    ··························· andn········· outa, OutPin1

    ···························· jmp········· #:FireingLoop1················· 'Loop endlessly

    syncdelay1···· long····· 5·········· 'Register to control waits between commands

    DirOut1······· long····· |< 12······ 'Set output pin
    OutPin1······· long····· |< 12······ 'Output pin
    Mark1········· long····· |< 9······· 'Zero mark pin
  • AribaAriba Posts: 2,687
    edited 2008-12-07 08:20
    OK, my comments:
    1) 'COGID one' gets the actual ID to the register 'one'. Why do you need that? 'one' must be defined as long. (word is not possible in the way you have done it).
    2) OutPutPin1 and DirOutPutPin1 are the same PinMasks. You need it only 1 time, but use it for DIRA and OUTA.
    3) CounterA is not right initialized if you only set the Counter mode. You need also to set the FRQA register:
    mov CNTRA,#0
    movi CNTRA,#%11111
    mov FRQA,#1
    But why not use the CNT register, instead of setting up a counter?
    4) You store the TurnOn/Off times to Cog registers, which are readable only inside the same cog. If you want use this values in Spin or another assembly cog you need to store theme to the Hub RAM with WRLONG (and read it with RDLONG in the other cog). For that you have to pass a shared HubRAM address to both cogs (in the PAR register).
    It will be easier to make this Syncdelay in the same cog as the Window counting.

    Andy
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2008-12-11 20:06
    There are too many duplicate threads here…I removed the newest one (apologies to Ariba, your post was lost). The other links back to this one. Please limit all replies on this subject to this thread.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Engineering
  • AribaAriba Posts: 2,687
    edited 2008-12-11 21:04
    krazyideas said...
    Hello,

    OK, so I got as far as I could with the help that you guys have given me. This time I will try and tell you excatly what I am trying to do.


    My dad is building an electric motor and he can make it spin. The problem is that his mechanical timeing device that he has does not allow him to be able to tune the motor at all.

    What he has is a disk with big magnets in it and then 6 sets of electro coils, 2 on either side of the disk. He runs his motor from 2000 RPM to 4000 RPM.



    So what I am trying to build for him is a program that allows him to be able to adjust his timeing while his motor is running.


    I have two driver programs. One that just relays and measures the puleses from his mechancal timeing, and another that ignors his timeing and just mimics and adjusts the puleses from his mechanical timeing.

    I have 6 sets of these two programs, one set for each coil. And I run each set in it's own cog to keep the speed of the programs up. Nice and short. The two never run at the same time.



    The one program is like the start up program, it just relays and measures his puleses. While the second one is the running program, it mimics the first without the pulse from the mechanical timeing. Allowing me to adjust the timeing while the motor is running. Going from anolog timeing to digital timeing.



    Then I have another program running in it's own cog that is measureing how many counts are in one degree of rotation, which is what I use to advance or retarde the timeing. I measure the counts it take for one degree of rotation so that if the motor slows down or speeds up I still change the timeing by the same amount.


    I have another program that is running the adjusting of the pulse's


    Comeing to a total of useing all 8 cogs.


    I still have some other things that I want to do. So I have another propellor chip. I have the Demo board and the PDB that I am useing.


    In the Demo board I am running

    -an RPM gage on a computer screen

    -an indicator of what degree each coil is turning on and off at on a TV screen

    -and a mini seral cable that I made.

    So I'm useing 6 cogs there.



    The mini seial cable I made uses 6 pins. I have it output a seires of highs and lows on those 6 pins depinding on what key on the keyboard I press. I hooked up that mini serial cable to 6 pins on the PDB to control my varubles. I know that it works because I hooked it all up and was makeing leds turn on and off on the PDB.



    I have not tested the RPM gage and the indicator program yet but it is lowest on the food chain of what need's to work



    I call the Demo Board program Master1, and the PDB program Master2



    So Master1 works well enough for me

    Master2 is where my problems are.

    Cog 1, Runs the start up program that starts the other cogs and then waits for a dip switch on pin 21 to go high then it switches from the first driver program (ReadFireTime1, and 2 and 3 ect) to the second driver program (ExicuteFireTime1,and 2 ect)

    after which it starts running the pulse adjusting program which is the reciver for my mini serial cable. I have delays in that program so that a led will light up when the PDB recives a key from the Demo board and will only count it as one change. Then if the dip switch makes pin 21 goes low then it returns to the ReadFireTime programs.



    Cog2, Runs the program that give me the counts in one degree of rotation to adjust the pulses with



    Cogs 3 through 8 Run my driver Programs



    I do belive that most everything is working right except for my driver programs.



    What I need to happen is the pulses from the ReadFireTime programs that are stored in WinStart1, WinEnd1, ect to be stored in global variables TurnOn1, TurnOff1, ect.

    So that when I switch from the ReadFireTime programs to the ExicuteFireTime programs, I can adjust TurnOn1, TurnOff1, ect and then send them to the ExicuteFireTime Cogs or my driver programs, allowing me to change at will when each pulse turns on and how long it stays on for.


    Now in the driver programs I have a zero mark that is 180 degrees from the begging of the pulse where the counter starts at zero, this is so that if there is a small error in the pulse it is not multiplyed with each rotation, but is contained only in that one rotation which allows each pulse to turn on at the same degree each rotation and then adjust it with the keyboard through my mini seral cable reciver program.


    Also this sloves the problem of switching between my driver programs and keeping in the right timeing, other wise by the time that I switched from ReadFireTime to ExicuteFireTime I would be way off and be starting retarded and it wouldn't work.



    Something else is The reason that I use the CNTA is so the when I am subtracting the counts of when pulses turn on and off I never end up trying to subtract 4 billion from 700 or something like that, because I reset the PHSA counter each loop. So my mesurements are always right



    So I think that is as clear as I can get. I'm really bad at getting across what I mean to say, you can ask my wife.

    Let me know what you think,

    I finaly got my computer to attach files so it will be easyer to read this time around


    Also I know that there are probly a thousand better ways to do this but I just need help to get this to work so if it can work Please help me get on the right path


    Thanks so much for the help guys. There is NO way I could even get this far with out all the help I have gotten from you vetrans.


    I hope I'm close.

    Sorry krazyideas, your code is to complicated for me. It's easier to show you a simpler approach, than go into the details of your code.

    I have attached a Spin file which uses only 2 Spin cogs for doing much of what you want (+ 2 cogs for Keyboard and Display).
    It's not a ready to use solution, but can give you some more ideas.
    It is set up to output 6 pulses on Pins P0..P5 slow enough that you can watch the pulses on 6 connected LEDs. You can change the 6 Pins in a table in the DAT section.
    Changing the values is done with Cursor keys and number key 1..6 to select which output should change. Also recording of 6 Marker pins (over 1 turn) is implemented.

    Spin is fast enough to control your motor (4000 rpm = 66 turns/second = 15ms for a turn), so no need for Assembly cogs and parameter passing.
    To speed the code up for your motor, just set the speed variable to 1000..3000 you can change it 'while running with keys.

    Andy
  • krazyideaskrazyideas Posts: 119
    edited 2008-12-12 02:12
    Thanks Guys
Sign In or Register to comment.