I need help with assembly lanugage for my senior project
Hello Everyone,
This is my first post on the parallax forum and I am trying to get my senior project working by April 16 for the IEEE student activities conference. My partner and I are building a micromouse and we chose to use the propeller as our processor. We initially used spin but the code was not executing fast enough for our needs. I am now trying to re write all of our codes into assembly in the next two weeks but I still can't figure out how to pass values from one cogs assembly code to another cog. The first cog reads serial signal from two AD converters and the second cog will be in charge of driving straight.
Can someone write a simple example of how to pass this information? I have thoroughly skimmed over "Programming the Parallax Propeller using Machine Language" and searched through the forum for the past week with no success on this particular subject (I am bad at searching through forums). I now the information is out there in numerous places but cant seem to find any of those places. Any help would be greatly appreciated as my partner and I are on a narrowing deadline.
I also dont understand the purpose or advantage of objects. Though I would prefer not to use objects to retain understanding of my current code, can someone still elaborate on them for me?
This is my first post on the parallax forum and I am trying to get my senior project working by April 16 for the IEEE student activities conference. My partner and I are building a micromouse and we chose to use the propeller as our processor. We initially used spin but the code was not executing fast enough for our needs. I am now trying to re write all of our codes into assembly in the next two weeks but I still can't figure out how to pass values from one cogs assembly code to another cog. The first cog reads serial signal from two AD converters and the second cog will be in charge of driving straight.
Can someone write a simple example of how to pass this information? I have thoroughly skimmed over "Programming the Parallax Propeller using Machine Language" and searched through the forum for the past week with no success on this particular subject (I am bad at searching through forums). I now the information is out there in numerous places but cant seem to find any of those places. Any help would be greatly appreciated as my partner and I are on a narrowing deadline.
I also dont understand the purpose or advantage of objects. Though I would prefer not to use objects to retain understanding of my current code, can someone still elaborate on them for me?
Comments
Also, you'll find that people on this forum are very helpful, but there's a general expectation that you show some effort before asking others to start doing work for you. This is much more of a "teach a person to fish" rather than "give a person a fish" community.
If not, rewriting everything in ASM will be very hard in a few days.
There are languages for the prop available which compile to code much faster than spin but slower than pasm. If a speedup by a factor of 4-5 is good enough for your project it might be easier to code it in C and use the catalina C compiler or to code it in basic and use the propbasic compiler.
What you save is the complexity to introduce some IPC for the cogs.
You can pick some common locations at the top of hub ram, and each cog can write or read to those locations. Start at $7FFF and work down.
Or you could create a variable in your main spin program, then pass the location of that variable to each cog using PAR when you start the cog. You can also pass the location of an array. This method has the advantage that both cogs and spin have access to the variable.
I agree. I could write pages on why I agree, but it might cause an endless debate here and distract from your immediate task which is to get something working in a limited amount of time.
What works well on this forum is to post some code fragments and ask a simple question. The forum works 24/7 and I've had answers sometimes within a few minutes, often to questions that are hard to find in the manual.
Any chance you could post what code you have? (warts and all, that is ok!)
-- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp10.pdf
Here is the portion of the code I have written so far. I already know I could simplify it to be much faster but that is not my current priority. The clock is already set for 80 MHz in the CON section.
'--------------------------------------------------------------------------------------------------- VAR Word PushButton '---------------------------------------------------------------------------------------------------- PUB IR_Sensors Dira[4]~ 'This portion of the code prevents the program Repeat ' from starting until an external button is pushed PushButton := INA[4] ' on the top of the micromouse, allowin the user to While PushButton < 1 ' center the robot in the starting corner of the maze Waitcnt(clkfreq + cnt) Cognew(@ADCclock,0) 'Cog to run the clock for the AD converter Cognew(@SerIn,1000) 'Cog to read the Serial outputs from 2 ADC0831 converters 'Cognew(@Motor,2000) 'Cog used to run steering and basic motion '--------------------------------------------------------------------------------------------------------- DAT ORG 0 ADCclock MOV DIRA,ClockPinout 'Toggles pins 16 and 23 high and low at 100KHz CLKLoop MOV OUTA,ClockPinout ' to create clock signal for the ADCs CALL #ClkDelay NOP 'Keeps the signal at a 50% duty cycle NOP MOV OUTA, #0 CALL #ClkDelay JMP #CLKLoop ClkDelay Mov DelayVal,#46 'Subroutine used to generate the delay between DelayLoop SUB DelayVal,#1 ' high and low cycles. TJNZ DelayVal,#DelayLoop ClkDelay_RET RET DelayVal LONG 0 'Variable for creating the delay to reach 100KHz ClockPinout LONG $810000 'Activates pins 16 and 23 for clock signal '----------------------------------------------------------------------------------------------- DAT ORG 0 'First part of the code reads the first SerIn MOV DIRA,IRMask ' five bits of the Right Sensor ADC MOV OUTA,IRMask SerLoop MOV OUTA,LBReadMask 'CK enable for the first adc CALL #CKFollow CALL #CKFollow MOV RRange,INA AND RRange,DATMaskR ROL RRange,#1 CALL #CKFollow MOV RRange,INA AND RRange,DATMaskR ROL RRange,#1 CALL #CKFollow MOV RRange,INA AND RRange,DATMaskR ROL RRange,#1 CALL #CKFollow MOV RRange,INA AND RRange,DATMaskR ROL RRange,#1 CALL #CKFollow MOV RRange,INA AND RRange,DATMaskR ROL RRange,#1 CALL #CKFollow CALL #CKFollow CALL #CKFollow CALL #CKFollow MOV OUTA,RBReadMask 'This remaining part of the code reads CALL #CKFollow ' the first five bits of the Left sensor CALL #CKFollow ' second ADC MOV LRange,INA AND LRange,DATMaskL ROL LRange,#1 CALL #CKFollow MOV LRange,INA AND LRange,DATMaskL ROL LRange,#1 CALL #CKFollow MOV LRange,INA AND LRange,DATMaskL ROL LRange,#1 CALL #CKFollow MOV LRange,INA AND LRange,DATMaskL ROL LRange,#1 CALL #CKFollow MOV LRange,INA AND LRange,DATMaskL ROL LRange,#1 CALL #CKFollow CALL #CKFollow CALL #CKFollow CALL #CKFollow MOV DIRA,IRMask MOV RSenVal,RRange 'Stores final range values into variables MOV LSenVal,LRange ' that will remain consistent through the JMP #SerLoop ' sampling period. CKFollow CKHigh MOV CLKMask,CKMask 'This Subroutine makes this cog wait AND CLKMask,INA ' unil the clock cog completes one TJZ CLKMask,#CKHigh ' oscillation before sampling a bit CKLow MOV CLKMask,CKMask AND CLKMask,INA TJNZ CLKMask,#CKLow CKFollow_RET RET LBReadMask LONG $40000 RBReadMask LONG $80000 IRMask LONG $C0000 CKMask LONG $400000 CLKMask LONG $400000 DATMaskR LONG $4000 DATMaskL LONG $8000 RRange LONG 0 LRange LONG 0 RSenVal LONG 0 LSenVal LONG 0 '-------------------------------------------------------------------------------------- {DAT ORG 0 Motor MotorStart GoStraight 'Straight JMP #MotorStart TurnLeft MOV OUTA,TLeftPins 'Turn Left MOV X,LeftDelay CALL #MovDel JMP #MotorStart TurnRight MOV OUTA,TRightPins 'Turn Right MOV X,RightDelay CALL #MovDel JMP #MotorStart TurnLeft MOV OUTA,TLeftPins 'Turn 180 degrees MOV X,RotateDelay CALL #MovDel JMP #MotorStart MovDel SUB X,#1 TJNZ #MovementDelay MovDel_RET RET X WORD 0 StraightDelay WORD 0 LeftDelay WORD 0 RightDelay WORD 0 RotateDelay WORD 0 LeftSenVal LONG 0 RightSenVal LONG 0 TRightPins LONG %0110 TLeftPins LONG %1001 ForMainPins LONG %0101 }
I saw an example of bringing a global variable into ram by using MOV X, par but I could not find the location in the dat file where one of the global variable was actually copied to the local variable. Do I also have to make a comment when initializing a cog that lists the variable being passed into its ram?This is a very brief note in pseudo code and for one variable
1) create a variable in the main program "myvariable" or in a var section of the main program
2) when starting the cog, make the second parameter "@myvariable". This passes the location of myvariable in hub to the cog - this location may change each time you edit your main program. (It does not pass the value of myvariable, only the location)
3) In the cog startup code, MOV cogvariable,par
4) use rdlong and wrlong to move data to and from this location in hub, noting the source/destination order of rdlong vs wrlong. See Jonnymac's article near the bottom.
Given that a micromouse is a mechanical device we might be surprised that it cannot be controlled fast enough in Spin. But without knowing more about the aims of your project and it's actual code we can only offer general advice on speeding things up.
It is in the nature of most programs that there is a bottle neck somewhere. That is to say that there might be only one part of your code that is critical and causing major performance loss.
In that case there is no point rewriting all of your code in PASM or otherwise optimizing it. You may only need to speed up some small critical part some where.
If 90% of your time were spent in only 10% of the code then obviously speeding up that 10% has a much bigger effect, the other 90% can remain "as is".
So the trick might be to identify where that critical 10% is in your code. and concentrate optimization efforts on that. Avoid "premature optimization" as they say.
After all if your code works now but the time taken to rewrite and debug it in PASM takes you passed your project deadline that's not a very good optimization.
As a simple example, constant folding: most compilers will optimize constant portions of an expression, like this:
X := Y * (80_000_000 / 1000) ' X = y milliseconds
The Spin compiler will evaluate that expression completely at runtime, unless you tell it not to, like this:
X := Y * constant(80_000_000 / 1000) ' X = y milliseconds
Just a couple of possibilities:
1- rewrite it in propbasic. It creates assembly code, so you'll be blazing fast.
2- optimize and speed up the critical parts as suggested by Humanoido. After finding bottlenecks, in case spin is not fast enough you could:
2a- use assembly code as a kind of coprocessor (check float objects as example)
2b- use spinlmm or inline assembly (both in the obex)
Massimo
RS_Jim
CON _clkmode = xtal1 + pll16x 'Use crystal*8 for a speed of 40_000_000 Hz _xinfreq = 5_000_000 'External 5 MHz crystal XI & XO 'Instructons summary on page 40 of TM '------------------------------------------------------------------------------ VAR LONG SHARED '--------------------------------------------------------------------------- PUB Micromouse_Assembly_PBLED cognew(@PButtonLED,@SHARED) cognew(@OUTPUT,@SHARED) '--------------------------------------------------------------------------- DAT ORG 0 PButtonLED MOV GlobalStore,PAR MOV DIRA,BVal LittleLoop MOV BPIN,INA 'Check Value of Push Button ADD GlobalStore,#1 NOP AND BPIN,CMask WRLONG BPIN,GlobalStore 'Copies value to HUB Ram MOV OUTA,#0 TJZ BPIN,#NLGHT MOV OUTA,BVal 'Turn LED1 on if Push Button is on NLGHT JMP #LittleLoop BVal LONG %100_0000 BPIN LONG 0 CMask LONG %1_0000 GlobalStore LONG 0 '--------------------------------------------------------------------------- DAT ORG 0 OUTPUT MOV GlobalStore2,PAR ADD GlobalStore2,#1 MOV DIRA,PINL OLoop RDLONG PINVal,GlobalStore2 'Read Value from hub ram ROL PINVal,#3 MOV OUTA,PINVal 'Use Value to light LED2 JMP #OLoop PINVal LONG 0 PINL LONG %1000_0000 GlobalStore2 LONG 0
if you really want your data in your global var "shared" you should do your wrlong back to par or globalstore unmodified.
RS_Jim