Yes, it is a normal object.
No, it does not start another cog (which has never been the requirement of an object).
The P2 interpreter cog has empty space at the bottom of its memory and uses this to run your inline assembly. When a method that uses inline assembly is encountered, the interpreter does this:
1. Copy method parameters, return value(s) (if present), local variables (if present), and code to the low part of the interpreter cog.
2. The interpreter calls your code like an assembly subroutine
3. When done, the interpreter returns the parameters, return values, and locals to the high-level code.
This seems like it would take a lot of time, but it doesn't; the P2 was designed to move data between cogs and the hub very quickly. Inline assembly is one of my favorite features of the P2. If you need code to run fast but not be running all the time, it is the perfect solution.
In the end, the assembly code is running in a cog -- the interpreter cog which is already running, hence we don't need to spawn another (like we did in the P1).
BTW, there is a mechanism -- that I haven't used yet -- to install custom assembly subroutines into the interpreter cog and call them at any time from Spin.
@JonnyMac said:
Okay, I translated my MCP3202 code to the P2 using inline PASM2 instead of a cog.
Jon,
I got your 3202 object running today. Found one small error in one of your comments in your Read Object. ' ' --mode is 0 for single-ended, 1 for differential...... should be ' --mode is 1 for single-ended, 0 for differential.
Once I figured out it was running in differential mode( I was applying same voltage source to both channels, and it would only show 0 on both channels), and changed it to singled-ended, your object runs great. So I tested it in both modes and it works. Thanks!
Wonder if you can have a look at the attached code, and tell me what I am doing wrong. I have an Object called Tstop in my Demo program that allows me to time performance of 3202 in P2 vs P1. I am using FloatMath_2 to calculate seconds, but am getting crazy number when I convert it to a float number, as you can see in the debug.log. Can't tell if it is a bad FloatMath_2 object, or I am not formatting the output correctly.
So I tested it in both modes and it works. Thanks!
Excellent. Glad to know that.
In my P2 template, I have the timing values at the top, including constants for microseconds and milliseconds based on the system frequency.
con { timing }
CLK_FREQ = 200_000_000 ' system freq as a constant
MS_001 = CLK_FREQ / 1_000 ' ticks in 1ms
US_001 = CLK_FREQ / 1_000_000 ' ticks in 1us
_clkfreq = CLK_FREQ ' set system clock
The MS_001 and US_001 constants -- derived from the system frequency -- make precision loops and code timing trivial. Here is how I time code:
t := getct()
' code to test
t := getct() - t - 40 ' timing in system ticks
us := (t + (US_001 >> 1)) / US_001 ' convert to microseconds
I tend to leave things in system ticks which has the best resolution. If you want to move to a "human" unit, the last line above shows how easy it is to convert the value to microseconds. No FP library is required to get precision timing.
...but am getting crazy number when I convert it to a float number...
I don't think you can use udec() to output a number that has been converted to floating point format. You understand that floats have a different internal structure than standard values, right?
See for yourself. Start with this constant:
con
ONE = 1.0
Now do this:
debug(udec_(ONE))
debug(udec_(1))
See the difference?
Finally...
Please do me a favor: 1) Either use my code as is, or 2) Take my name off of any code you modify for redistribution. If you feel the need to take one of my files and modify it, I don't want credit (or blame) for what you do. Remove the jm_ from the name (as you did), and also remove any instance of "Jon McPhalen" and my email address from the listing. I work hard at what I do and am very sensitive to people refusing to follow my simple formatting guidelines. Do it your way, just don't include my name in any of your work.
These are my opinions, of course, but then, you asked for my opinions.
-- Don't put specific pin numbers in a child object unless the object is for a fixed device like the serial/debug port, P1 EEPROM, or P2 Flash
-- Don't attempt to set _clkfreq from a child object
-- If you want to stay on my good side, don't make a mess of my carefully-crafted code.
Found one small error in one of your comments in your Read Object...
Verified and fixed. Thank you for pointing that out.
Sorry Jon, I seemed to have upset you. I didn't realize I had made a mess of your code. I guess you are referring to the chip outline I changed. My intent was not to post my code under your name, but I now see the error of my ways...I should not have included it in my previous comment to you for others to see, my bad. Sorry, it won't happen again. Thanks again for your help.
Comments
Yes, it is a normal object.
No, it does not start another cog (which has never been the requirement of an object).
The P2 interpreter cog has empty space at the bottom of its memory and uses this to run your inline assembly. When a method that uses inline assembly is encountered, the interpreter does this:
1. Copy method parameters, return value(s) (if present), local variables (if present), and code to the low part of the interpreter cog.
2. The interpreter calls your code like an assembly subroutine
3. When done, the interpreter returns the parameters, return values, and locals to the high-level code.
This seems like it would take a lot of time, but it doesn't; the P2 was designed to move data between cogs and the hub very quickly. Inline assembly is one of my favorite features of the P2. If you need code to run fast but not be running all the time, it is the perfect solution.
In the end, the assembly code is running in a cog -- the interpreter cog which is already running, hence we don't need to spawn another (like we did in the P1).
BTW, there is a mechanism -- that I haven't used yet -- to install custom assembly subroutines into the interpreter cog and call them at any time from Spin.
Jon,
I got your 3202 object running today. Found one small error in one of your comments in your Read Object. ' ' --mode is 0 for single-ended, 1 for differential...... should be ' --mode is 1 for single-ended, 0 for differential.
Once I figured out it was running in differential mode( I was applying same voltage source to both channels, and it would only show 0 on both channels), and changed it to singled-ended, your object runs great. So I tested it in both modes and it works. Thanks!
Wonder if you can have a look at the attached code, and tell me what I am doing wrong. I have an Object called Tstop in my Demo program that allows me to time performance of 3202 in P2 vs P1. I am using FloatMath_2 to calculate seconds, but am getting crazy number when I convert it to a float number, as you can see in the debug.log. Can't tell if it is a bad FloatMath_2 object, or I am not formatting the output correctly.
Excellent. Glad to know that.
In my P2 template, I have the timing values at the top, including constants for microseconds and milliseconds based on the system frequency.
The MS_001 and US_001 constants -- derived from the system frequency -- make precision loops and code timing trivial. Here is how I time code:
I tend to leave things in system ticks which has the best resolution. If you want to move to a "human" unit, the last line above shows how easy it is to convert the value to microseconds. No FP library is required to get precision timing.
I don't think you can use udec() to output a number that has been converted to floating point format. You understand that floats have a different internal structure than standard values, right?
See for yourself. Start with this constant:
Now do this:
See the difference?
Finally...
Please do me a favor: 1) Either use my code as is, or 2) Take my name off of any code you modify for redistribution. If you feel the need to take one of my files and modify it, I don't want credit (or blame) for what you do. Remove the jm_ from the name (as you did), and also remove any instance of "Jon McPhalen" and my email address from the listing. I work hard at what I do and am very sensitive to people refusing to follow my simple formatting guidelines. Do it your way, just don't include my name in any of your work.
These are my opinions, of course, but then, you asked for my opinions.
-- Don't put specific pin numbers in a child object unless the object is for a fixed device like the serial/debug port, P1 EEPROM, or P2 Flash
-- Don't attempt to set _clkfreq from a child object
-- If you want to stay on my good side, don't make a mess of my carefully-crafted code.
Verified and fixed. Thank you for pointing that out.
Sorry Jon, I seemed to have upset you. I didn't realize I had made a mess of your code. I guess you are referring to the chip outline I changed. My intent was not to post my code under your name, but I now see the error of my ways...I should not have included it in my previous comment to you for others to see, my bad. Sorry, it won't happen again. Thanks again for your help.