@evanh said:
Isn't that just using the system ticks variable, after waiting on human input, to produce a seed? That shouldn't be hard to replicate.
After a P1 reset the system ticks variable is always the same when the program starts executing. Asking for user input adds some randomness to the timing before the system timer is consulted. The P2 has a source of randomness I could use - but the P1 doesn't have such a thing (AFAIK).
PS: The Prop2's startup seed comes from ADC sampling noise I think.
EDIT: Yep ... Ha, it just samples the bitstream direct. 50 x 31 bits = 1550 random bits.
' Seed xoroshiro 128** using delta-sigma ADC bits from calibration mode
'
wrpin ##$00100000,#rx_pin 'put rx pin in adc gio calibration mode
mov x,#50 'ready to seed 50 times with 31 bits
.seed rep #2,#31 'get 31 bits (31*4 clocks = 124/20 = ~6us)
testp #rx_pin wc
rcl y,#1
bith y,#31 'seed via hubset
hubset y
djnz x,#.seed
wrpin #0,#rx_pin 'return rx pin to normal mode
EDIT2: I think Xoroshiro 128** is a typo on Chip's behave. I'm pretty sure that was the original Xoroshiro 128+ algorithm used to make the free-running global generator. Dunno why he typed a double asterisk.
EDIT3: The mark-space ratio of GIO level will be around 20% ones to 80% zeros. There will be aliasing beat patterns with patches of all zeros in the sysclock/4 sampling. Still, no two will be the same.
Right, I thought you were targetting compatibility for those old programs is all.
Using only built-in features of the Prop1 might be tricky alright .... maybe trying spamming a counter's PLL divider to keep it unstable ... but that would need to use a pin for output I suspect ... could momentarily use the comms TX pin if no other was suitable.
EDIT: Ah, not the divider, that's just a post-VCO divider. It's the PLL's input coming from the main PHSx counter that is important for stability of the VCO in the PLL. So spamming lots of changes to FRQx to upset the PLL's reference frequency should then keep the PLL unstable. Just toggling between two target frequencies should be enough.
Then just have to collect the output. It could be done like Chip did in the Prop2 - treat the pin as bitstream directly. Or another way might be take timing measurements with the second counter.
@evanh said:
Using only built-in features of the Prop1 might be tricky alright .... maybe trying spamming a counter's PLL divider to keep it unstable ... but that would need to use a pin for output I suspect ... could momentarily use the comms TX pin if no other was suitable.
EDIT: Ah, not the divider, that's just a post-VCO divider. It's the PLL's input coming from the main PHSx counter that is important for stability of the VCO in the PLL. So spamming lots of changes to FRQx to upset the PLL's reference frequency should then keep the PLL unstable. Just toggling between two target frequencies should be enough.
Huh, yeah, same idea but different implementation. Also somehow is extracting the random bits from the PHSx register. That implies PHSx is in some way integral to the VCO loop inside the PLL. Or is maybe looped back from the PLL output. I don't know enough about the Prop1 to understand the detail.
EDIT: Ahhh, the video out can be driven by a counter. So it's the WAITVID instruction that is sampling the counter's PLL jitter. Chip is just looping that back in with the ADD PHSA,CNT
This is a full release. I was embarrassed not to have known about Chip's RealRandom object so I thought I had better put out a new release to incorporate it. The addition of the new RANDOM plugin is the only significant new feature, and it is only required on the Propeller 1. I use it in Dumbo Basic to eliminate the need to ask for user input when seeding the random number generator.
Here is the relevant extract from the README.TXT:
RELEASE 7.3
New Functionality
-----------------
1. A new random number plugin has been added for the Propeller 1, based on
Chip Gracey's RealRandom.spin. The plugin is enabled by defining the
Catalina symbol RANDOM. For example:
catalina ex_random.c -lci -C RANDOM
Note that a random number generator is built into the Propeller 2, so the
plugin is not required on that platform. The RANDOM plugin occupies a
cog on the Propeller 1. It generates random data continuously, and writes
a new 32 bit random number to the second long in its registry entry
approximately every 100us (at 80Mhz).
C provides a pseudo random number generator called rand() and this must
be seeded using the srand() function, otherwise it will always return
the same sequence of pseudo random numbers.
In previous releases, the getrand() function was a "stopgap" function -
it generated true random data on the Propeller 2, but on the Propeller 1
it only generated pseudo random data, seeded by the system clock. However,
there are good reasons to have both a pseudo random number generator and
a true random number generator, so with the addition of the new Propeller
1 RANDOM plugin, getrand() has been modified to always generate 32 bit
pseudo random numbers seeded by the system clock on both the Propeller 1
and 2, and a new getrealrand() function has been added which returns a 32
bit true random number on both the Propeller 1 and 2 (provided the RANDOM
plugin has been loaded on the Propeller 1). If the RANDOM plugin has not
been loaded (which may be because there is not a spare cog available) on
the Propeller 1 then getrealrand() uses the same technique as getrand().
The new getrealrand() function will generate unique random numbers in
situations where the Propeller 1 previously would not, such as if a
program was automatically started immediately after power up. In such
situations the system clock would be reset, so the previous technique
of seeding a pseudo random number generator with the system clock would
always generate the same sequence of pseudo random numbers.
Here is a summary of the random number routines:
rand(), srand() -> rand() generates pseudo random numbers, in the
range 0 to MAX_RAND (32767), and srand() can
be used to seed the random number generator
getrand() -> getrand() generates 32 bits of pseudo random
data using rand(). On first call it also seeds
the random number generator using srand() and
the current system clock. This avoids the need
to explicitly call srand()
getrealrand() -> getrealrand() returns 32 bits of random data.
On the Propeller 1 this will be true random data
if the RANDOM plugin is loaded, otherwise it
will use the same technique as getrand(). On the
Propeller 2 it always returns true random data.
The program ex_random.c in demos/examples has been updated to demonstrate
both rand() and getrand() (which both generate pseudo random numbers) as
well as the getrealrand() function (which generates true random numbers).
2 Dumbo Basic has been updated to allow the use of the new getrealrand()
function (described in point 1, above). A new RANDOM option has been
added to the RANDOMIZE statement to seed Basic's built in pseudo random
number generator with getrealrand().
Here are all the RANDOMIZE options:
RANDOMIZE -> prompt for the seed
RANDOMIZE TIMER -> use the the current time as the seed
RANDOMIZE <expr> -> use <expr> as the seed
RANDOMIZE RANDOM -> use getrealrand() as the seed (on the P2,
or when compiled with RANDOM on the P1) or
else prompt for the seed (note this is an
extension to GW Basic).
The RND function has been extended to allow for the generation of either
pseudo random or true random numbers. Instead of just RND, use RND(x)
where ...
x > 0 generates the next pseudo random number
x = 0 returns the last random number generated (pseudo or true)
x < 0 generates a true random number (note this is an extension to GW
Basic, where x < 0 reseeds the random number generator - but
that can also be done using the RANDOMIZE statement).
Dumbo Basic now enables the RANDOM plugin by default when built for the
Propeller 1, and the basic demo programs poker.bas, blackjck.bas,
startrek.bas and ut-trek.bas have been updated to use the RANDOM option
of the RANDOMIZE statement instead of the TIMER option, which depended
on variations in user input to generate a random seed.
3. Dumbo Basic's USING clause (used in PRINT, PRINT# and LPRINT statements)
now accepts more GW Basic format options:
+ : a '+' indicates a leading sign will be printed (i.e. '+' or '-')
except as noted for '-' (below). The '+' also counts as another
digit in the output. In GW Basic the '+' must be in the first
position of the USING clause, but in Dumbo Basic it can appear
in any position before any decimal point (the actual position
makes no difference - the sign will always be printed immediately
before the number). Note that (unlike GW Basic) Dumbo Basic always
prints a sign for negative numbers - adding '+' makes it also
include a leading sign for positive numbers.
- : a '-' anywhere in the clause indicates a trailing sign will be
printed for negative numbers. The '-' does NOT count as another
digit in the output - if the number is not negative, a space
will be printed in its place. In GW Basic the '-' must be
in the last position of the USING clause, but in Dumbo Basic
it can be in any position (the actual position makes no
difference - the '-' will always be printed immediately after
the number). If both '+' and '-' are included in the same USING
clause then the '+' is just treated as another digit position.
^^^^ : a '^^^^' anywhere in the clause indicates an exponent of form
'ESNN' will be used, where E is the letter 'E', S is the sign
of the exponent and NN is the 2 digit exponent. The '^'
characters do NOT count as additional digits - they always
indicate an exponent. In GW Basic the '^^^^' must appear at
the end of the USING clause, but in Dumbo Basic it can be in
any 4 consecutive positions. The actual position makes no
difference.
For example, the statements:
PRINT USING "##.#^^^^"; 0.001
PRINT USING "+#.#^^^^"; 0.001
PRINT USING "##.#^^^^"; -0.001
PRINT USING "+#.#^^^^"; -0.001
PRINT USING "+#.#^^^^-"; 0.001
PRINT USING "##.#^^^^-"; -0.001
PRINT USING "+#.#^^^^-"; -0.001
would result in the following output:
1.0E-03
+1.0E-03
-1.0E-03
-1.0E-03
+1.0E-03
1.0E-03-
1.0E-03-
Other Changes.
--------------
1. The pseudo random number generator getrand() was returning only 31 bits
of random data, not 32. Affected the Propeller 1 only.
2. Dumbo Basic was not correctly keeping track of the current position in the
current line of output, which meant using ',' as a separator to move to
the next 14 character print zone did not always end up with the output in
the correct position. Affected Dumbo Basic on the Propeller 1, Propeller 2,
and also on Windows and Linux.
3. All the Dumbo Basic example programs are now UNIX format files, not DOS
format files. This makes them easier to edit using vi on Catalyst, which
expects UNIX format files by default. Affected Dumbo Basic on the Propeller
1, Propeller 2, and also on Windows and Linux.
It's been so long since I added a new Propeller 1 plugin that I made notes as I figured out how to do it all over again. Catalina's registry architecture is well suited to this kind of plugin, so this was possibly the easiest one I have ever added - which makes it ideal to document for future reference:
These instructions show the steps used in creating the new RANDOM plugin and
making it accessible via a new C library function.
Note that these instructions only include details for adding the plugin to
the Propeller 1 default target (which is in the directory 'target\p1'), but
similar steps apply to other other targets that also need to include the new
plugin (such as the embedded target which is in directory 'embedded\p1').
Also note that the details for adding new plugins to Propeller 2 targets are
similar in concept but differ in detail, but are not included because the
RANDOM plugin is only applicable to the Propeller 1.
Step 1. Create the plugin from the existing Spin file
In this case the file target\p1\Catalina_RND_plugin.spin
was created from RealRandom.spin by adding code to register
the plugin on start up, and to write the results back to the
registry instead of a Spin variable. Examine these two files
for more details.
Step 2. Define a constant for the plugin
Plugin constants are defined in the Spin file:
target\p1\Catalina_Common.spin
where the following was added:
LMM_RND = 32 ' Random Number Generator
and also in the C file:
source\lib\include\plugin.h
where the following was added:
#define LMM_RND 32
Step 3. Define a name for the plugin
Plugin names (e.g. used when printing the registry)
are defined in:
source\lib\catalina\plugname.c
where the following was added:
case LMM_RND : return "Random Number Generator";
Step 4. Add the plugin to Extras.spin
Extra plugins are loaded from the file:
target\p1\Extras.spin
where the following was added to the OBJ declarations:
#ifdef RANDOM
RND : "Catalina_RND_Plugin"
#endif
and the following was added to the Setup function:
#ifdef RANDOM
RND.Setup
#endif
and the following was added to the Start function:
#ifdef RANDOM
RND.Start
#endif
Step 5. Define a function to access the plugin
In this case, the function was defined in:
source\lib\include\prop.h
where the following was added:
int getrealrand();
Step 6. Write a function to access the plugin
In this case the function was created in:
source\lib\catalina\getrealrand.c
where the following code was added to locate the plugin in the
registry and (if found) read a new random number from the
appropriate registry entry:
#include <prop.h>
#include <plugin.h>
int getrealrand() {
static int cog = -1;
static request_t *request_block = NULL;
static int last_random = 0;
int new_random = 0;
if (cog == -1) {
cog = _locate_plugin(LMM_RND);
if (cog >= 0) {
request_block = REQUEST_BLOCK(cog);
}
}
if (request_block) {
// RANDOM plugin loaded - wait for a new random
while ((new_random == 0) || (new_random == last_random)) {
new_random = request_block->response;
}
last_random = new_random;
}
else {
// RANDOM not loaded - fall back to getrand()
new_random = getrand();
last_random = new_random;
}
return new_random;
}
Step 7. Modify the relevant Makefile to build the library function
In this case the relevant Makefile is:
source\lib\catalina\Makefile
where the following line was added:
getrealrand.s \
Step 8. Rebuild the C library
In the directory:
source\catalina\lib
execute the following command:
build_all
This is a patch release that must be installed over an existing Catalina 7.3 installation.
Here is the relevant extract from the README.TXT:
RELEASE 7.3.1
New Functionality
-----------------
1. None.
Other Changes.
--------------
1. When the alloca() function was added (release 7.0) it increased the stack
requirements for all programs very slightly, but the stack sizes allocated
for Factories in the Multi-Processing version of Lua was not updated. This
led to various issues but the most obvious was that Lua programs that tried
to use the sbrk function to defragment the C heap would not run correctly.
Affected the Propeller 2 only.
It would be quite feasible to make the random routine into a library only call without the need for another cog. Obviously such an implementation will consume processing time and use the counterA+vid hardware of the cog it runs on, but I'd suspect those will generally not be in use on the primary C cog anyway.
Something I have meant to do on every release, and keep forgetting ...
The two Lua versions of Startrek (star.lua and star-tos.lua) both contain code that deliberately slows down the program output. The intention is to simulate how the game would have appeared on an old slow teletype terminal. Amusing, but a nuisance on a screen. To disable this, use the vi text editor and find the line that says:
@evanh said:
It would be quite feasible to make the random routine into a library only call without the need for another cog. Obviously such an implementation will consume processing time and use the counterA+vid hardware of the cog it runs on, but I'd suspect those will generally not be in use on the primary C cog anyway.
Yes. Also, it would be good enough for most purposes to just generate one truly random number on startup, to use as a seed for the pseudo random number generator. Then re-use the cog.
Either or both of these might make it into a release at some point. But at least Catalina now has an option for a real random number generator on the Propeller 1, which was something that was missing.
@Rayman said:
Ok, I'm pretty sure it's C, but haven't seen the term ANSI there...
If it's coded in what is commonly referred to as 'clean C' (which is the subset of C and C++ that any C or C++ compiler will compile successfully) then it could be converted to ANSI C without much effort.
But if you want a modern multi-paradigm scripting language, I'd choose Lua over Python any day. And we already have Lua on the Propeller.
@RossH said:
One more question - did you follow all the instructions in BUILD.TXT? In particular, before doing ./build_all, did you build awka? The version of awka in the distribution may depend on GLIBC 2.34 but you should be able to rebuild it to use whatever version you have installed:
cd $LCCDIR/source/catalina/awka-0.7.5
./configure CFLAGS="-m32"
make
Thanks, no, I'd only read the README.Linux file at that stage. Got it compiled now.
Testing with "hello_world.c" and I've managed to upset Payload in two ways already:
First, I used my usual way of exiting from terminal mode in Loadp2, which is CTRL-Z, and this leaves the comport dangling and can't be used again. Power-cycling the USB connection to the Prop2 Eval Board reassigns a new port to the device and can be used there.
Second, Payload only appears to work with /dev/ttyXXXX port names. If I try to specify something like /dev/serial/by-id/usb-XXXX then it won't find the port.
@RossH said:
One more question - did you follow all the instructions in BUILD.TXT? In particular, before doing ./build_all, did you build awka? The version of awka in the distribution may depend on GLIBC 2.34 but you should be able to rebuild it to use whatever version you have installed:
cd $LCCDIR/source/catalina/awka-0.7.5
./configure CFLAGS="-m32"
make
Thanks, no, I'd only read the README.Linux file at that stage. Got it compiled now.
Testing with "hello_world.c" and I've managed to upset Payload in two ways already:
First, I used my usual way of exiting from terminal mode in Loadp2, which is CTRL-Z, and this leaves the comport dangling and can't be used again. Power-cycling the USB connection to the Prop2 Eval Board reassigns a new port to the device and can be used there.
Second, Payload only appears to work with /dev/ttyXXXX port names. If I try to specify something like /dev/serial/by-id/usb-XXXX then it won't find the port.
The CTRL-Z issue is not to do with payload. In a linux bash shell, CTRL-Z puts the active process in the background (i.e. it suspends it). To resume it, use the command "fg".
You should be able to use the -p option of payload to specify the port by name. For instance, I can say:
payload -i hello_world -p /dev/ttyUSB0
Try the command payload -v and tell me if it prints your ports correctly. For instance, here is what I get:
Catalina Payload 7.0
verbose mode
usage: payload [options] propeller_file [catalina_file ...]
options: -? or -h print this helpful message and exit (-v for more help)
-a port find ports automatically, starting from specified port
-A key set attention key (default is 1, 0 disables)
-b baud use specified baudrate
-B baud same as -b
-c cpu cpu destination for catalina download (default is 1)
-d diagnostic mode (-d again for more diagnostics)
-e program the EEPROM with the program loaded
-f msec set interfile delay in milliseconds (default is 500)
-g c,r set terminal columns and rows - default is 80,24
-i interactive mode - act as terminal after load
-I term interactive mode - run program 'term' after load
-j disable lfsr check altogether
-k msec set interpage delay in milliseconds (default is 0)
-K msec set key delay time in milliseconds (default is 25)
-l use old style lfsr check (slower)
-L name execute the named Lua script after opening the port
-m max set max_attempts (default is 5)
-n msec set sync timeout in milliseconds (default is 100)
-o vers override Propeller version detection (vers 1 = P1, 2 = P2)
-p port use port for downloads (just first download if -s used)
-q mode line mode (1=ignore CR,2=ignore LF,4=CR to LF,8=LF to CR,
16=CR to LF on output - modes can be combined!)
-r msec set reset delay in milliseconds (default is 0)
-s port switch to port for second and subsequent downloads
-S msec set YModem char delay time in milliseconds (default is 0)
-t msec set read timeout in milliseconds (default is 1000)
-T msec set YModem timeout in milliseconds (default is 3000)
-u msec set reset time in milliseconds (default is 15)
-v verbose mode (or include port numbers in help message)
-w wait for a keypress between each load
-x do catalina download only (boot loader already loaded)
-y do not display download progress messages
-z double reset
port can be:
1 = /dev/ttyS0
2 = /dev/ttyS1
3 = /dev/ttyS2
4 = /dev/ttyS3
5 = /dev/ttyS4
6 = /dev/ttyS5
7 = /dev/ttyS6
8 = /dev/ttyS7
9 = /dev/ttyS8
10 = /dev/ttyS9
11 = /dev/ttyS10
12 = /dev/ttyS11
13 = /dev/ttyS12
14 = /dev/ttyS13
15 = /dev/ttyS14
16 = /dev/ttyS15
17 = /dev/ttyUSB0
18 = /dev/ttyUSB1
19 = /dev/ttyUSB2
20 = /dev/ttyUSB3
21 = /dev/ttyUSB4
22 = /dev/ttyUSB5
This is a full release. The main purpose of this release is to include some performance enhancements that I have been working on in the background. The enhancements are specific to Propeller 2 XMM programs. Speed improvements of between 10% and 25% are typical, depending on the program itself.
I have hopes for further improvements, but I was getting tired of trying to keep multiple streams of development going, and I thought the enhancements had reached a point where it was worth bringing them into the main release stream so that I did not have to do that any more.
See the README.TXT for more details. Note that the improvements are not enabled by default - you have to explicitly enable them when you compile your program.
Here is the relevant extract from the README.TXT:
RELEASE 7.4
New Functionality
-----------------
1. Two new benchmarks (Whetstone & Dhrystone) have been added in the
demos\benchmarks folder.These are used to help assess the improvements
in XMM performance and also the new XMM options added in this release
(see point 2 below). The existing benchmarks (fibo.c and ackerman.c) were
not very useful for assessing XMM programs because they are so small they
typically fit entirely in the cache, so are not representative of programs
that require XMM RAM. They also did not test floating point performance.
The benchmarks have been modified very slightly from the originals,
primarily to remove the need to interact with them.
They are applicable to both the Propeller 1 and the Propeller 2.
2. The overall XMM speed has been increased on the Propeller 2, and new
XMM related compile-time options have been added that can be used to
increase the speed further in specific instances. These changes are
applicable to the Propeller 2 only.
The basic speed of all XMM (SMALL or LARGE) programs has been increased
by between 4% and 8% (the exact improvement depends on the program, the
memory model used and the size of the cache used).
Additional speed improvements (up to 25% in some cases) can be achieved
by defining one or more of the following new Catalina symbols:
LUT_PAGE : Use the LUT to hold the current cache page and execute XMM
code from there instead of from Hub RAM. The page size can
be up to 1k (the second 1k of LUT is used as a common code
library). The page size limit of 1k constrains the cache
geometries that can be used. More details on this are given
in target\p2\constant.inc
LUT_CACHE : Use the LUT to hold the entire XMM cache. This must be
combined with CACHED_1K. It gives good performance with
a very small cache size, and frees up valuable Hub RAM
for other purposes. Only one of LUT_PAGE and LUT_CACHE
can be specified.
CACHE_PINS : Use 2 pins in repository mode to communicate between the
XMM kernel and the XMM cache, instead of communicating via
Hub RAM. The pins used are specified in the platform
configuration file (e.g. P2EDGE.inc) and cannot be used
for any other purpose.
FLOAT_PINS : Use 4 pins in repository mode to communicate between the
XMM kernel and the Floating point plugin instead of via
Hub RAM. The pins used are specified in the platform
configuration file (e.g. P2EDGE.inc) and cannot be used
for any other purpose. FLOAT_PINS is only supported by
the Float_C plugin, which is the one loaded by default
when the XMM kernel is used, or when the -lmc option is
specified on the command line.
Unfortunately, no single combination of the above options gives the "best"
performance in all possible circumstances - the results depend on the
program, the memory model and cache size used, and how much floating
point is used by the program.
In general, specifying all of LUT_PAGE, CACHE_PINS and FLOAT_PINS gives
good results in most cases, and will typically result in a speed increase
of around 10% for XMM LARGE programs, and 20% for XMM SMALL programs. A
real-world example of this is that when these options are applied to the
self-hosted version of the Catalina compiler itself (which is compiled in
LARGE mode) it results in an increase in compilation speed of about 10%.
Below are some actual numbers from the benchmark programs.
First, the following common options were set in CATALINA_DEFINE:
set CATALINA_DEFINE=LARGE CACHED_64K OPTIMIZE MHZ_200 CLOCK
then the fibo, dhrystone and whetstone benchmarks were compiled as follows:
cd demos\benchmarks
catalina -p2 -lci fibo.c <plus other options - see table below>
catalina -p2 -lc -lmc whetstone.c <plus other options - see table below>
catalina -p2 -lc -lmc -D MSC_CLOCK -DCLK_TCK=1000 dhry_1.c dhry_2.c
<plus other options - see table below>
This gives the following results (Release 7.3 is included in the table
as a baseline):
Catalina Other Options fibo drystone whetstone
Release (added using -C) (msecs) (VAX KIPS) (KWIPS)
======== ============================== ======= ========== =========
7.3 3064 677 877
7.4 2828 719 917
7.4 CACHE_PINS 2828 746 951
7.4 FLOAT_PINS 2828 721 980
7.4 CACHE_PINS FLOAT_PINS 2828 746 1000
7.4 LUT_PAGE 2412 671 862
7.4 LUT_PAGE CACHE_PINS 2412 710 909
7.4 LUT_PAGE FLOAT_PINS 2412 686 917
7.4 LUT_PAGE CACHE_PINS FLOAT_PINS 2412 710 970
Another result worth noting is that the LUT_CACHE option can be used to
free up to an additional 63k of Hub RAM - i.e. it requires only 1k for
the XMM cache, yet gives performance quite comparable with Release 7.3
when using 64k for the cache (as shown in the table above):
Catalina Other Options fibo drystone whetstone
Release (added using -C) (msecs) (VAX KIPS) (KWIPS)
======== ============================== ======= ========== =========
7.4 LUT_CACHE CACHE_PINS FLOAT_PINS 3145 512 847
Note that none of these options are enabled by default because they depend
on the LUT not being required for other purposes, and also on the platform
having sufficient unused pins available. A good choice for the pins to use
are the unused pins when the RTC add-on board is used (which uses only 2
pins out of the 8 pins the board physically occupies) - these are the
defaults used in the platform files.
3. A new Propeller 1 demo program (random.c) has been added in demos\random.
This program demonstrates the RANDOM plugin, and also demonstrates how
to manually load and unload plugins at run-time.
Other Changes.
--------------
1. The _unregister_plugin() library function was putting zero in the plugin
type in the registry (which actually means LMM_VMM - i.e. an LMM kernel)
instead of putting in the value 255 (which is LMM_NUL). This made no
difference when a new plugin was loaded into a free cog using ANY_COG
(which is the usual way to load plugins) but may have given the wrong
results when the registry was displayed, or if the registry was searched
for a free cog to load based on the plugin type in the registry.
Affected both the Propeller 1 and Propeller 2.
2. The Propeller 2 PSRAM and HyperRAM demo programs in demos/p2_ram were
broken by the addition of environment variables, which prevented some
programs from building because the initialization code was too large.
Affected the Propeller 2 only.
EDIT: Something that is perhaps not made clear enough in the documentation of the new cache options is that when you use the LUT as part of the cache, the XMM Kernel cog and the XMM Cache cog have to be in the same cog pair so that they share the same LUT - e.g. cogs 0 and cog 1. For instance, the XMM Cache cog may write a page of code to the LUT which the XMM kernel cog then executes, or the XMM Kernel cog may write data to the LUT which the XMM Cache cog will later write back to the XMM RAM. In previous releases the cache cog (if required) was always loaded in cog 7. This is all handled internally, and I have not found any instances where this change makes any difference, but it is possible that some programs may still expect the cache to always be in cog 7, in which case they will not work with the new options.
@RossH said:
The CTRL-Z issue is not to do with payload. In a linux bash shell, CTRL-Z puts the active process in the background (i.e. it suspends it). To resume it, use the command "fg".
Oh, ha, I guess Eric has a hook or something setup in Loadp2 to quit instead.
You should be able to use the -p option of payload to specify the port by name. For instance, I can say:
payload -i hello_world -p /dev/ttyUSB0
Yeah, those work fine. I would like, however, to use alternative port paths that are device tied rather than the order of connection/discovery. Then I can have multiple Prop2's plugged in together and load specific programs to specific boards. Handy for testing.
Not a biggie though. I've found I can happily use Loadp2 in place of Payload.
Yeah, those work fine. I would like, however, to use alternative port paths that are device tied rather than the order of connection/discovery. Then I can have multiple Prop2's plugged in together and load specific programs to specific boards. Handy for testing.
Not a biggie though. I've found I can happily use Loadp2 in place of Payload.
Ok, I see what you mean now. But you will need to use payload to load XMM programs, so here is a solution:
First, see this page, which describes what we will do ...
Then execute ./build_all script in /source/catalina to rebuild payload, and now whenever you plug a Parallax prop-plug in, you can just say something like ...
payload -i hello_world -p /dev/PropPlug1
A variation on this should get you what you need. For instance, you could add PropPlug2 ... etc etc.
Note that my example rule file will assign any Parallax PropPlug to /dev/PropPlug1 - to make sure the same PropPlug is always assigned to the same name, you need to find a unique identifier for it and add that to the rules file.
I tried adding the pre-existing /dev/serial/... symlinks to Payload but it didn't work for whatever reason. Following your instructions works. New /etc/udev/rules.d/99-usb-serial.rules rule file made:
@evanh said:
I tried adding the pre-existing /dev/serial/... symlinks to Payload but it didn't work for whatever reason. Following your instructions works. New /etc/udev/rules.d/99-usb-serial.rules rule file made:
Next step. I don't know what my options are here ... I have an existing Spin object that I use as a library function within Flexspin C projects. The primary function of it is called pllset(). https://obex.parallax.com/obex/pllset/
I'd like to make it useable as a function in Catalina too. There is Spin2 specific things in it that are important - namely the compiler created symbols clkmode_ and clkfreq_ which provides the compile time board crystal config. I could make a backup copy at boot time but since these have always been provided by Spin2 I make use of them.
And the accompanying Cordic maths would be a nice to have as well.
A notable side effect of pllset() is any attached serial port connected with a serial terminal will also need its baud recomputed. This used to be coded explicitly in Flexspin but these days is incorporated in _clkset() now I think. I no longer have to do anything for printf() to function across runtime dynamic sysclock frequencies. Presumably happened when Spin2's debug gained the same.
@evanh said:
Next step. I don't know what my options are here ... I have an existing Spin object that I use as a library function within Flexspin C projects. The primary function of it is called pllset(). https://obex.parallax.com/obex/pllset/
I'd like to make it useable as a function in Catalina too. There is Spin2 specific things in it that are important - namely the compiler created symbols clkmode_ and clkfreq_ which provides the compile time board crystal config. I could make a backup copy at boot time but since these have always been provided by Spin2 I make use of them.
And the accompanying Cordic maths would be a nice to have as well.
A notable side effect of pllset() is any attached serial port connected with a serial terminal will also need its baud recomputed. This used to be coded explicitly in Flexspin but these days is incorporated in _clkset() now I think. I no longer have to do anything for printf() to function across runtime dynamic sysclock frequencies. Presumably happened when Spin2's debug gained the same.
The Spin2 code can be converted directly to C. I usually do this manually, but Eric had a tool to do it automatically called spin2cpp, which I have used, but I don't remember the details. I do remember that things like the _clkmode and _clkfreq symbols needed to be converted into Catalina calls to _clockmode() and _clockfreq() - I wrote a header file to do this automatically - see the file /include/spin2cpp.h - all I have to do is remember how to use it! **
PASM code can generally be translated fairly directly into Catalina's inline PASM - at least for NATIVE mode programs that do not have multi-threading, which I think is the only mode that Flexspin C supports.
The main "gotcha" to be aware of with inline PASM when multi-threading is enabled, or when the program is compiled in other Catalina modes (i.e. COMPACT, TINY, XMM SMALL or XMM LARGE) is the setq instruction - because there is no guarantee that the setq and the instruction that uses the Q register (usually the immediately following instruction) will end up being executed sequentially - and an intervening instruction may disrupt the Q register. You can solve this when multi-threading by adding stalli and allowi instructions to prevent context switching. Solving it for the other modes is a little more difficult, but certainly possible - for instance, for LMM TINY mode kernel, I added some new kernel primitives - see the file /target/p2/lmmklib.inc
The capability to automatically recalculate the serial baud rate "on the fly" would have to be added to the serial plugin. None of my serial plugins do that, but it would certainly be possible to create one that does.
Ross.
** It is used automatically when you #include propeller2.h - see next post!
Comments
After a P1 reset the system ticks variable is always the same when the program starts executing. Asking for user input adds some randomness to the timing before the system timer is consulted. The P2 has a source of randomness I could use - but the P1 doesn't have such a thing (AFAIK).
Ross.
I'm lost. Is the user input not an option?
PS: The Prop2's startup seed comes from ADC sampling noise I think.
EDIT: Yep ... Ha, it just samples the bitstream direct. 50 x 31 bits = 1550 random bits.
EDIT2: I think Xoroshiro 128** is a typo on Chip's behave. I'm pretty sure that was the original Xoroshiro 128+ algorithm used to make the free-running global generator. Dunno why he typed a double asterisk.
EDIT3: The mark-space ratio of GIO level will be around 20% ones to 80% zeros. There will be aliasing beat patterns with patches of all zeros in the sysclock/4 sampling. Still, no two will be the same.
Yes, that's why I do it.
But I would like not to have to add a line like that to every P1 program that needs random numbers.
EDIT: For instance, what if the program does not otherwise require any user input? How to seed a random number generator on the P1 in that case?
Right, I thought you were targetting compatibility for those old programs is all.
Using only built-in features of the Prop1 might be tricky alright .... maybe trying spamming a counter's PLL divider to keep it unstable ... but that would need to use a pin for output I suspect ... could momentarily use the comms TX pin if no other was suitable.
EDIT: Ah, not the divider, that's just a post-VCO divider. It's the PLL's input coming from the main PHSx counter that is important for stability of the VCO in the PLL. So spamming lots of changes to FRQx to upset the PLL's reference frequency should then keep the PLL unstable. Just toggling between two target frequencies should be enough.
Then just have to collect the output. It could be done like Chip did in the Prop2 - treat the pin as bitstream directly. Or another way might be take timing measurements with the second counter.
This sounds like what Chip's RealRandom object does: https://obex.parallax.com/obex/real-random/
Huh, yeah, same idea but different implementation. Also somehow is extracting the random bits from the PHSx register. That implies PHSx is in some way integral to the VCO loop inside the PLL. Or is maybe looped back from the PLL output. I don't know enough about the Prop1 to understand the detail.
EDIT: Ahhh, the video out can be driven by a counter. So it's the WAITVID instruction that is sampling the counter's PLL jitter. Chip is just looping that back in with the ADD PHSA,CNT
Aha! I didn't know about that object. I'll investigate incorporating it. Thanks.
Ross.
Catalina 7.3 has been released here.
This is a full release. I was embarrassed not to have known about Chip's RealRandom object so I thought I had better put out a new release to incorporate it. The addition of the new RANDOM plugin is the only significant new feature, and it is only required on the Propeller 1. I use it in Dumbo Basic to eliminate the need to ask for user input when seeding the random number generator.
Here is the relevant extract from the README.TXT:
It's been so long since I added a new Propeller 1 plugin that I made notes as I figured out how to do it all over again. Catalina's registry architecture is well suited to this kind of plugin, so this was possibly the easiest one I have ever added - which makes it ideal to document for future reference:
Ross.
Deleting this post as it has been superseded by the Catalina 7.3.1 patch release.
Ross.
Catalina 7.3.1 has been released here.
This is a patch release that must be installed over an existing Catalina 7.3 installation.
Here is the relevant extract from the README.TXT:
It would be quite feasible to make the random routine into a library only call without the need for another cog. Obviously such an implementation will consume processing time and use the counterA+vid hardware of the cog it runs on, but I'd suspect those will generally not be in use on the primary C cog anyway.
Something I have meant to do on every release, and keep forgetting ...
The two Lua versions of Startrek (star.lua and star-tos.lua) both contain code that deliberately slows down the program output. The intention is to simulate how the game would have appeared on an old slow teletype terminal. Amusing, but a nuisance on a screen. To disable this, use the vi text editor and find the line that says:
DisableTeleprint = false
and change it to ...
DisableTeleprint = true
Now, go save the Federation!
Yes. Also, it would be good enough for most purposes to just generate one truly random number on startup, to use as a seed for the pseudo random number generator. Then re-use the cog.
Either or both of these might make it into a release at some point. But at least Catalina now has an option for a real random number generator on the Propeller 1, which was something that was missing.
@RossH Did you ever take a stab at compiling Micropython? Or, is it not ansi compliant enough for that?
No, I've not tried it. My understanding (but keep in mind that I am not a Python expert) is that Python is written in ANSI C, but Micropython is not.
Ross.
Ok, I'm pretty sure it's C, but haven't seen the term ANSI there...
If it's coded in what is commonly referred to as 'clean C' (which is the subset of C and C++ that any C or C++ compiler will compile successfully) then it could be converted to ANSI C without much effort.
But if you want a modern multi-paradigm scripting language, I'd choose Lua over Python any day. And we already have Lua on the Propeller.
Ross.
Moved from topic - https://forums.parallax.com/discussion/comment/1559583/#Comment_1559583
Thanks, no, I'd only read the README.Linux file at that stage. Got it compiled now.
Testing with "hello_world.c" and I've managed to upset Payload in two ways already:
The CTRL-Z issue is not to do with payload. In a linux bash shell, CTRL-Z puts the active process in the background (i.e. it suspends it). To resume it, use the command "fg".
You should be able to use the -p option of payload to specify the port by name. For instance, I can say:
payload -i hello_world -p /dev/ttyUSB0
Try the command
payload -v
and tell me if it prints your ports correctly. For instance, here is what I get:So I can also use the command:
payload -i hello_world -p 17
Catalina 7.4 has been released here.
This is a full release. The main purpose of this release is to include some performance enhancements that I have been working on in the background. The enhancements are specific to Propeller 2 XMM programs. Speed improvements of between 10% and 25% are typical, depending on the program itself.
I have hopes for further improvements, but I was getting tired of trying to keep multiple streams of development going, and I thought the enhancements had reached a point where it was worth bringing them into the main release stream so that I did not have to do that any more.
See the README.TXT for more details. Note that the improvements are not enabled by default - you have to explicitly enable them when you compile your program.
Here is the relevant extract from the README.TXT:
EDIT: Something that is perhaps not made clear enough in the documentation of the new cache options is that when you use the LUT as part of the cache, the XMM Kernel cog and the XMM Cache cog have to be in the same cog pair so that they share the same LUT - e.g. cogs 0 and cog 1. For instance, the XMM Cache cog may write a page of code to the LUT which the XMM kernel cog then executes, or the XMM Kernel cog may write data to the LUT which the XMM Cache cog will later write back to the XMM RAM. In previous releases the cache cog (if required) was always loaded in cog 7. This is all handled internally, and I have not found any instances where this change makes any difference, but it is possible that some programs may still expect the cache to always be in cog 7, in which case they will not work with the new options.
Oh, ha, I guess Eric has a hook or something setup in Loadp2 to quit instead.
Yeah, those work fine. I would like, however, to use alternative port paths that are device tied rather than the order of connection/discovery. Then I can have multiple Prop2's plugged in together and load specific programs to specific boards. Handy for testing.
Not a biggie though. I've found I can happily use Loadp2 in place of Payload.
Ok, I see what you mean now. But you will need to use payload to load XMM programs, so here is a solution:
First, see this page, which describes what we will do ...
https://inegm.medium.com/persistent-names-for-usb-serial-devices-in-linux-dev-ttyusbx-dev-custom-name-fd49b5db9af1
I followed those instructions to create /dev/PropPlug1 by adding the following line to /etc/udev/rules.d/99-usb-serial.rules ....
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{product}=="PropPlug", ATTRS{manufacturer}=="Parallax Inc", SYMLINK+="PropPlug1"
Then, I made the following changes in /source/catalina/rs232.c ...
Then execute ./build_all script in /source/catalina to rebuild payload, and now whenever you plug a Parallax prop-plug in, you can just say something like ...
payload -i hello_world -p /dev/PropPlug1
A variation on this should get you what you need. For instance, you could add PropPlug2 ... etc etc.
Note that my example rule file will assign any Parallax PropPlug to /dev/PropPlug1 - to make sure the same PropPlug is always assigned to the same name, you need to find a unique identifier for it and add that to the rules file.
Ross.
I tried adding the pre-existing /dev/serial/... symlinks to Payload but it didn't work for whatever reason. Following your instructions works. New /etc/udev/rules.d/99-usb-serial.rules rule file made:
Well, I would probably have just called them something like "PropPlug1", "PropPlug2" & "PropPlug3" to save typing - but then I'm just lazy!
Glad you got it working!
Ross.
Done
I had become used to the existing naming so wasn't too phased by working with the serial numbers. And I use name completion of course.
Any idea why the existing symlinks don't work?
Next step. I don't know what my options are here ... I have an existing Spin object that I use as a library function within Flexspin C projects. The primary function of it is called pllset(). https://obex.parallax.com/obex/pllset/
I'd like to make it useable as a function in Catalina too. There is Spin2 specific things in it that are important - namely the compiler created symbols
clkmode_
andclkfreq_
which provides the compile time board crystal config. I could make a backup copy at boot time but since these have always been provided by Spin2 I make use of them.And the accompanying Cordic maths would be a nice to have as well.
A notable side effect of pllset() is any attached serial port connected with a serial terminal will also need its baud recomputed. This used to be coded explicitly in Flexspin but these days is incorporated in _clkset() now I think. I no longer have to do anything for printf() to function across runtime dynamic sysclock frequencies. Presumably happened when Spin2's debug gained the same.
No. I was going to suggest that myself as a possible alternative. Perhaps a permissions problem? Does stty -F work on the symlinks?
The permissions bits on symlinks are ignored on Linux. Only the permissions bits on the symlink's referent can ever have any effect.
The Spin2 code can be converted directly to C. I usually do this manually, but Eric had a tool to do it automatically called spin2cpp, which I have used, but I don't remember the details. I do remember that things like the _clkmode and _clkfreq symbols needed to be converted into Catalina calls to _clockmode() and _clockfreq() - I wrote a header file to do this automatically - see the file /include/spin2cpp.h - all I have to do is remember how to use it! **
PASM code can generally be translated fairly directly into Catalina's inline PASM - at least for NATIVE mode programs that do not have multi-threading, which I think is the only mode that Flexspin C supports.
The main "gotcha" to be aware of with inline PASM when multi-threading is enabled, or when the program is compiled in other Catalina modes (i.e. COMPACT, TINY, XMM SMALL or XMM LARGE) is the setq instruction - because there is no guarantee that the setq and the instruction that uses the Q register (usually the immediately following instruction) will end up being executed sequentially - and an intervening instruction may disrupt the Q register. You can solve this when multi-threading by adding stalli and allowi instructions to prevent context switching. Solving it for the other modes is a little more difficult, but certainly possible - for instance, for LMM TINY mode kernel, I added some new kernel primitives - see the file /target/p2/lmmklib.inc
The capability to automatically recalculate the serial baud rate "on the fly" would have to be added to the serial plugin. None of my serial plugins do that, but it would certainly be possible to create one that does.
Ross.
** It is used automatically when you
#include propeller2.h
- see next post!