The top 16KB of hub contains the ROM code at boot time. That code contains constants that can be used to determine Rev A or Rev B chips. There is no difference from Rev B to Rev C except the ADC internal track cut and I guess that could be determined by code.
It'd be nice to have a way of reserving memory, but not initializing it.
I've got some big arrays that I'm sure slow down the compile and load process.
The stack/free mechanism in Spin1 can work, but kind of a pain. I don't think it's used much...
Be nicer if you could declare arrays in a DAT section that are just reserved, not initialized...
Sorta like RES in PASM...
Maybe a keyword like "stack"? Like this:
DAT 'graphics demo data
'Making these 4x bigger for super graphics demo
BitmapTiles stack $aaaa5555[16*x_tiles*y_tiles*4] 'this is tile data working buffer
DisplayTiles stack $11110[16*x_tiles*y_tiles*4] 'this is tile data that is being displayed
or, maybe use "*"
DAT 'graphics demo data
'Making these 4x bigger for super graphics demo
BitmapTiles long* $aaaa5555[16*x_tiles*y_tiles*4] 'this is tile data working buffer
DisplayTiles long* $11110[16*x_tiles*y_tiles*4] 'this is tile data that is being displayed
In the Spin2 documentation, under "Program Structure", there's a minimal PASM-only program:
loop DRVRND #56 ADDPINS 7 'write a random pattern to P63..P56
WAITX ##clkfreq_/10 'wait 1/10th of a second, loop
JMP #loop
This works...
However, if you try to use clkfreq_ in a Spin2/PASM program, the value seems to always be set to 20_000_000 rather than the actual clock frequency. Bug? My misinterpretation of the documentation? Or do I have to use hub location $44 to get the clock frequency in a Spin2/PASM program?
In the Spin2 documentation, under "Program Structure", there's a minimal PASM-only program:
loop DRVRND #56 ADDPINS 7 'write a random pattern to P63..P56
WAITX ##clkfreq_/10 'wait 1/10th of a second, loop
JMP #loop
This works...
However, if you try to use clkfreq_ in a Spin2/PASM program, the value seems to always be set to 20_000_000 rather than the actual clock frequency. Bug? My misinterpretation of the documentation? Or do I have to use hub location $44 to get the clock frequency in a Spin2/PASM program?
_RCFAST (20MHz) is the default.
Add this line to your program:
CON _clkfreq = 250_000_000
Then, you can use CLKMODE_ in a HUBSET instruction to set the mode:
%00100 = pulse/cycle output
This mode overrides OUT to control the pin output state.
X[15:0] establishes a base period in clock cycles which forms the empirical high-time and low-time units.
X[31:16] establishes a value to which the base period counter will be compared to on each clock cycle, as it counts from
X[15:0] down to 1, before starting over at X[15:0] if decremented Y > 0. On each clock, if the base period counter > X[31:16]
and Y > 0, the output will be high (else low).
Whenever Y[31:0] is written with a non-zero value, the pin will begin outputting a high pulse or cycles, starting at the next base
period.
Some examples:
If X[31:16] is set to 0, the output will be high for the duration of Y > 0.
If X[15:0] is set to 3 and X[31:16] is set to 2, the output will be 0-0-1 (repeat) for the duration of Y > 0.
IN will be raised when the pulse or cycles complete, with the pin reverting to low output.
During reset (DIR=0), IN is low, the output is low, and Y is set to zero.
You need to do a WYPIN after enabling the smart pin to get it going.
In the Spin2 documentation, under "Program Structure", there's a minimal PASM-only program:
loop DRVRND #56 ADDPINS 7 'write a random pattern to P63..P56
WAITX ##clkfreq_/10 'wait 1/10th of a second, loop
JMP #loop
This works because the default clock frequency is 20_000_000.
However, if you try to use clkfreq_ in a Spin2/PASM, the value seems to always be set to 20_000_000 rather than the actual clock frequency. Bug? MiOr do I have to use hub location $44 to get the clock frequency in a Spin2/PASM program?
In the Spin2 documentation, under "Program Structure", there's a minimal PASM-only program:
loop DRVRND #56 ADDPINS 7 'write a random pattern to P63..P56
WAITX ##clkfreq_/10 'wait 1/10th of a second, loop
JMP #loop
This works...
However, if you try to use clkfreq_ in a Spin2/PASM program, the value seems to always be set to 20_000_000 rather than the actual clock frequency. Bug? My misinterpretation of the documentation? Or do I have to use hub location $44 to get the clock frequency in a Spin2/PASM program?
_RCFAST (20MHz) is the default.
Add this line to your program:
CON _clkfreq = 250_000_000
Then, you can use CLKMODE_ in a HUBSET instruction to set the mode:
I'm trying to determine the current clock frequency, not set it...
Chip has a section on system clock setting at the end of the spin2 document. It mentions "clkmode" and "clkfreq" for actively set variables. Note there's no underscore in variable names. And, yes, they are at fixed hubram addresses $40 and $44.
Underscores in constants from obj references are treated like underscores in constant values. In other words, they are placeholders rather than characters in the constant name:
testcon.spin2:
con
TEST_CONSTANT = 0
pub dummy()
testcon2.spin2:
obj
testcons : "TestCon"
pub start() | x
x := testcons.T_E_S_T_CONSTANT
The above will compile, even though there are extra underscores in the constant name.
A reference to testcons.TESTCONSTANT wlll also compile.
This doesn't seem to affect constants defined in the same spin2 file.
Edit:
References to nonexistent constants in obj references will be replaced with a zero value rather than raising a compile error.
Can anyone else duplicate this on their P2 eval board?
CON
_clkfreq = 200_000_000
PUB Example()
waitms(3000) ' Wait for all led's to go out
pinwrite(56, 0)
dira[1] := 0 ' This causes the led for pin 56 to go out after about 1 second,
' even though we will be executing the repeat loop below
' If you comment out this line, the led will stay on
pinwrite(57, 0)
repeat
pintoggle(58)
waitms(100)
The led for pin 56 should stay on regardless of the direction of pin 1. It appears that there's a strange delayed side effect for the dira assignment. Other pins for the dira assignment (I've tried only a few, such as 0, 2, and 20, along with dirb assignments) don't seem to cause this issue.
Or maybe my board is messed up? Or I'm messed up?
Edit:
It appears that I'm using dira[1] incorrectly, it should be dira.[1].
dira[1] := 0 is the same as dirb := 0. You just set the direction of pin 56 to input (and the direction of all the other pins of port B )
If you want to write bit 1 of DIRA then in Spin2 you need:
dira.[1] := 0
I am making a self-calibrating 8-channel ADC object that starts a PASM program in the registers not used by the Spin2 interpreter. It returns millivolts per each channel for Spin2 to use without any extra massaging. I discovered that I must shield CORDIC operations within the interpreter from interrupts, so that the PASM code running on interrupts can also use the CORDIC. Should have this working tomorrow. Now I must add several STALLI/ALLOWI instructions into the Spin2 interpreter and move things around to make everything fit again.
Chip,
Just pondering interrupts some more, it dawned on me that any stalled instruction can't be interrupted. Not just the WAITxxx instructions. So, for example, an XCONT instruction waiting on the streamer will also put a hold on IRQ response times.
Chip,
Just pondering interrupts some more, it dawned on me that any stalled instruction can't be interrupted. Not just the WAITxxx instructions. So, for example, an XCONT instruction waiting on the streamer will also put a hold on IRQ response times.
True, but those kinds of instructions aren't used in the interpreter. Everything that waits does loops.
I found and fixed a problem last night. I was using the CORDIC within my interrupt routine and I noticed it was interfering with the interpreter operation. So, I had to put STALLI and ALLOWI around interpreter routines that use the CORDIC. Now, there's not interference, but it has lengthened the interrupt-to-ISR time considerably - around 60 clocks for single CORDIC operations. WAITMS/WAITUS/GETSEC do double CORDIC operations, so they cause double the delay. I'm going to break those CORDIC sequences into two parts, where they each have their own STALLI/ALLOWI and a NOP in-between, if necessary, to allow ISR's better time granularity. I will post the latest PNut.exe soon. I've added lots of constant symbols for things that need them.
... for example, an XCONT instruction waiting on the streamer will also put a hold on IRQ response times.
True, but those kinds of instructions aren't used in the interpreter.
Ah, I was thinking more about the prop2 document:
When an interrupt event occurs, certain conditions must be met before the interrupt branch can happen:
- ALTxx / CRCNIB / SCA / SCAS / GETXACC / SETQ / SETQ2 / XORO32 / XBYTE must not be executing
- AUGS must not be executing or waiting for a S/# instruction
- AUGD must not be executing or waiting for a D/# instruction
- REP must not be executing or active
- STALLI must not be executing or active
- The cog must not be stalled in any WAITx instruction
obj
testaddr : "testaddr"
var
long core
pub start()
pinwrite(56 addpins 7, !((@core) >> 16))
repeat
Based on this (on a P2 eval board), the address of core has its uppermost 16 bits set to $xx20, which is an address > 2MB.
If you comment out the reference to testaddr, then the address of core has the uppermost bits set to $xx00, which is what I would expect.
Bug? Feature?
obj
testaddr : "testaddr"
var
long core
pub start()
pinwrite(56 addpins 7, !((@core) >> 16))
repeat
Based on this (on a P2 eval board), the address of core has its uppermost 16 bits set to $xx20, which is an address > 2MB.
If you comment out the reference to testaddr, then the address of core has the uppermost bits set to $xx00, which is what I would expect.
Bug? Feature?
So, this is because VBASE[31:20] holds the index of the first PUB to execute in a method pointer, which mechanism is used to start Spin2, both on app launch and COGSPIN launch. It's harmless, but annoying. I will see about getting rid of this anomaly. Thanks for pointing this out, Wmosscrop.
EDIT: Only the lower 20 bits of addresses matter in Spin2. The upper bits get ignored by the interpreter. But I will get this cleaned up.
Comments
Isn't there some catch when the jump is at the end of the rep block?
If relative jump there is an issue. Search this thread for more info:
http://forums.parallax.com/discussion/171254/tia-an-interactive-inline-assembler-for-taqoz
Also, I guess it's time to change that menu option text to "Identify Hardware", like Prop Tool, right?
Let's me know if it's alive or not...
I've got some big arrays that I'm sure slow down the compile and load process.
The stack/free mechanism in Spin1 can work, but kind of a pain. I don't think it's used much...
Be nicer if you could declare arrays in a DAT section that are just reserved, not initialized...
Sorta like RES in PASM...
Maybe a keyword like "stack"? Like this:
or, maybe use "*"
I've declared lots of symbols in the compiler for smart pins and streamer modes. The symbols are listed in the doc file, towards the end.
Now, if you want to make a 15k-high / strong-low pin, you can do this:
This works...
However, if you try to use clkfreq_ in a Spin2/PASM program, the value seems to always be set to 20_000_000 rather than the actual clock frequency. Bug? My misinterpretation of the documentation? Or do I have to use hub location $44 to get the clock frequency in a Spin2/PASM program?
_RCFAST (20MHz) is the default.
Add this line to your program:
CON _clkfreq = 250_000_000
Then, you can use CLKMODE_ in a HUBSET instruction to set the mode:
HUBSET ##clkmode_ & !3
WAITX ##20_000_000
HUBSET ##clkmode_
This is what I'm trying to make run. Nothing on the 'scope (which I setup using a simple loop with pinh/pinl). So, I tried this: Still nothing. Am I missing something in the mode setting?
You need to do a WYPIN after enabling the smart pin to get it going.
You need to set y after allowing the pin to run for pulse mode. y is forced to 0 until you let it run.
Edit: Chip beat me!
This works because the default clock frequency is 20_000_000.
However, if you try to use clkfreq_ in a Spin2/PASM, the value seems to always be set to 20_000_000 rather than the actual clock frequency. Bug? MiOr do I have to use hub location $44 to get the clock frequency in a Spin2/PASM program?
I'm trying to determine the current clock frequency, not set it...
@evanh
-- https://forums.parallax.com/discussion/169069/p2-tricks-traps-differences-between-p1-reference-material-only/p1
testcon.spin2: testcon2.spin2: The above will compile, even though there are extra underscores in the constant name.
A reference to testcons.TESTCONSTANT wlll also compile.
This doesn't seem to affect constants defined in the same spin2 file.
Edit:
References to nonexistent constants in obj references will be replaced with a zero value rather than raising a compile error.
The led for pin 56 should stay on regardless of the direction of pin 1. It appears that there's a strange delayed side effect for the dira assignment. Other pins for the dira assignment (I've tried only a few, such as 0, 2, and 20, along with dirb assignments) don't seem to cause this issue.
Or maybe my board is messed up? Or I'm messed up?
Edit:
It appears that I'm using dira[1] incorrectly, it should be dira.[1].
If you want to write bit 1 of DIRA then in Spin2 you need:
dira.[1] := 0
Andy
Just pondering interrupts some more, it dawned on me that any stalled instruction can't be interrupted. Not just the WAITxxx instructions. So, for example, an XCONT instruction waiting on the streamer will also put a hold on IRQ response times.
True, but those kinds of instructions aren't used in the interpreter. Everything that waits does loops.
I found and fixed a problem last night. I was using the CORDIC within my interrupt routine and I noticed it was interfering with the interpreter operation. So, I had to put STALLI and ALLOWI around interpreter routines that use the CORDIC. Now, there's not interference, but it has lengthened the interrupt-to-ISR time considerably - around 60 clocks for single CORDIC operations. WAITMS/WAITUS/GETSEC do double CORDIC operations, so they cause double the delay. I'm going to break those CORDIC sequences into two parts, where they each have their own STALLI/ALLOWI and a NOP in-between, if necessary, to allow ISR's better time granularity. I will post the latest PNut.exe soon. I've added lots of constant symbols for things that need them.
That last point should be extended.
file testaddr.spin2: file testaddrmain.spin2:
Based on this (on a P2 eval board), the address of core has its uppermost 16 bits set to $xx20, which is an address > 2MB.
If you comment out the reference to testaddr, then the address of core has the uppermost bits set to $xx00, which is what I would expect.
Bug? Feature?
So, this is because VBASE[31:20] holds the index of the first PUB to execute in a method pointer, which mechanism is used to start Spin2, both on app launch and COGSPIN launch. It's harmless, but annoying. I will see about getting rid of this anomaly. Thanks for pointing this out, Wmosscrop.
EDIT: Only the lower 20 bits of addresses matter in Spin2. The upper bits get ignored by the interpreter. But I will get this cleaned up.