00:19:25
##forth
<xentrac>
: minop over >r 2dup > >r xor r> and r> xor ;
00:20:08
##forth
<xentrac>
I was playing with a RISC-V branch-free min (as a stand-in for CMOV problems) and it occurred to me to translate it to assembly
00:20:15
##forth
<xentrac>
uh, to Forth
00:20:58
##forth
<xentrac>
I am not happy with the result
00:21:41
##forth
<xentrac>
six stack manipulations for four actual computational operations
00:29:31
##forth
<forthBot>
Environment for cleobuline inactive, freeing...
00:33:12
##forth
<xentrac>
forthBot: : minop over >r 2dup > >r xor r> and r> xor ;
00:33:12
##forth
<forthBot>
Unknown word in definition: over
00:33:13
##forth
<forthBot>
Error: Definition discarded due to error
00:33:20
##forth
<xentrac>
forthBot: : minop OVER >r 2dup > >r xor r> and r> xor ;
00:33:21
##forth
<forthBot>
Unknown word in definition: >r
00:33:21
##forth
<forthBot>
Error: Definition discarded due to error
00:33:26
##forth
<xentrac>
forthBot: : minop OVER >R 2dup > >r xor r> and r> xor ;
00:33:26
##forth
<forthBot>
Unknown word in definition: 2dup
00:33:26
##forth
<forthBot>
Error: Definition discarded due to error
00:33:43
##forth
<xentrac>
forthBot: : minop OVER >R 2DUP > >R XOR R> AND R> XOR ;
00:33:43
##forth
<forthBot>
Unknown word in definition: 2DUP
00:33:44
##forth
<forthBot>
Error: Definition discarded due to error
00:34:09
##forth
<xentrac>
anyway I feel like you could probably write a simpler branch-free min
00:57:04
##forth
<MrMobius>
forthBot: : minop OVER >R OVER OVER > >R XOR R> AND R> XOR ;
00:57:58
##forth
<MrMobius>
forthBot: 3 5 minop .s
00:57:58
##forth
<forthBot>
Error: Unknown word: .s
00:58:01
##forth
<MrMobius>
forthBot: 3 5 minop .S
00:58:02
##forth
<forthBot>
<2> 1 1
00:59:59
##forth
<xentrac>
hmm, that doesn't look like 3
01:02:18
##forth
<MrMobius>
works in seems to work in gforth
01:02:46
##forth
<xentrac>
yeah, it does
01:02:51
##forth
<xentrac>
forthBot: 3 4 > .
01:02:51
##forth
<forthBot>
0
01:02:58
##forth
<xentrac>
forthBot: 4 3 > .
01:02:58
##forth
<forthBot>
1
01:03:08
##forth
<xentrac>
oh, that's the problem, it's using the wrong value for "true"
01:03:13
##forth
<MrMobius>
forthBot: : foo 3 >R R> .S ; foo
01:03:13
##forth
<forthBot>
<3> 1 1 3
01:03:59
##forth
<MrMobius>
I like -1 as true
01:04:33
##forth
<xentrac>
I originally wrote the code on RISC-V, which also uses 1 for "true"
01:04:54
##forth
<xentrac>
so I had to invert the logic and subtract 1 from it
01:05:01
##forth
<xentrac>
in Forth that isn't necessary
01:07:41
##forth
<MrMobius>
xentrac: is this from Hacker's Delight by chance?
01:08:07
##forth
<MrMobius>
too bad there isnt a sign extension instruction for a single bit :P
01:09:31
##forth
<xentrac>
no, my original version was longer:
01:10:06
##forth
<xentrac>
minop: slt t0, a0, a1 # set t0 to "is a0 < a1?" (0 or 1)
01:10:07
##forth
<xentrac>
addi t0, t0, -1 # convert 0 to -1 (a0 ≥ a1) and 1 to 0 (a0 < a1)
01:10:09
##forth
<xentrac>
and t1, t0, a1 # t1 is now either 0 or, if a0 ≥ a1, a1
01:10:12
##forth
<xentrac>
xori t0, t0, -1 # negate t0. I don’t think RISC-V has a NOT
01:10:14
##forth
<xentrac>
and t2, t0, a0 # t2 is now either 0 or, if a0 < a1, a0
01:10:17
##forth
<xentrac>
or a0, t1, t2 # put the smaller of a0 and a1 into a0
01:10:20
##forth
<xentrac>
ret
01:10:29
##forth
<xentrac>
but then I gradually cut it down to:
01:10:44
##forth
<xentrac>
minopmin4:
01:10:44
##forth
<xentrac>
slt a2, a0, a1
01:10:46
##forth
<xentrac>
xor a0, a0, a1
01:10:49
##forth
<xentrac>
ret
01:11:20
##forth
<xentrac>
hopefully all the instructions are obvious other than `slt`
01:13:55
##forth
<xentrac>
I don't think Hacker's Delight has a branchless conditional move in it
01:14:00
##forth
<xentrac>
that's sort of out of its scope
01:16:44
##forth
<MrMobius>
nah, it's heavy on branchless stuff
01:19:45
##forth
<xentrac>
but mostly on computing things rather than just moving them around
01:20:27
##forth
<MrMobius>
branchless min starts on p42 of my copy
01:25:06
##forth
<xentrac>
I'll take a look
01:25:11
##forth
<MrMobius>
one of them uses movne for the generic RISC architecture it describes. MIPS v4 got movn but not on RISCV
01:26:05
##forth
<xentrac>
well, the context of this was that I was trying to measure how much it costs RISC-V to not have conditional move instructions in contexts where you need constant execution time
01:27:05
##forth
<MrMobius>
it does make me think about what instructions to add to the 7400 logic computer im planning
01:27:36
##forth
<xentrac>
the RV32I instruction set is quite pleasingly boring
01:27:54
##forth
<MrMobius>
some things either were never popular or maybe got added to some arch ive never seen
01:28:27
##forth
<MrMobius>
like loading one of two values based on carry which is kind of like cmov
01:28:32
##forth
<xentrac>
although Graeme Smecher's Minimax shows how you can get a significantly smaller design
01:29:11
##forth
<xentrac>
Minimax implements *only* the RV32IC compressed instructions, plus a few more
03:02:58
##forth
<forthBot>
Environment for xentrac inactive, freeing...
03:03:13
##forth
<forthBot>
Environment for MrMobius inactive, freeing...
03:15:47
##forth
<cleobuline>
forthBot: LOAD ini.fth
03:15:47
##forth
<forthBot>
File ini.fth with moon loaded
03:15:52
##forth
<cleobuline>
forthBot: : minop OVER >R 2DUP > >R XOR R> AND R> XOR ;
03:19:46
##forth
<cleobuline>
forthBot: 1 2 minop .S
03:19:46
##forth
<forthBot>
<1> 1
03:19:59
##forth
<cleobuline>
forthBot: 3 1 minop .S
03:19:59
##forth
<forthBot>
<2> 1 1
03:20:25
##forth
<cleobuline>
forthBot: 43 5 MIN .S
03:20:25
##forth
<forthBot>
<3> 1 1 5
03:20:38
##forth
<cleobuline>
forthBot: 43 5 MAX .S
03:20:39
##forth
<forthBot>
<4> 1 1 5 43
03:21:48
##forth
<xentrac>
cleobuline: that definition of minop doesn't work because > produces the wrong "true" value, 1 instead of -1
03:22:16
##forth
<cleobuline>
ha
03:22:58
##forth
<cleobuline>
true is just 0 <>
03:29:36
##forth
<tpbsd>
not here on Mecrisp-Stellaris Forth on Cortex-M " 4 2 > . -1 ok."
03:30:12
##forth
<tpbsd>
everyone has their own opinion of the truth ;-)
03:47:56
##forth
<cleobuline>
false == 0
03:48:09
##forth
<cleobuline>
anny number id true
03:48:24
##forth
<cleobuline>
is
03:56:11
##forth
<lf94>
tabemann_: Does INTR_GPIO_EDGE_HIGH@ return 0 (off) and 1 (on) or 0 and -1?
03:56:18
##forth
<lf94>
Not clear to me
03:58:50
##forth
<cleobuline>
forthBot: : test IF -1 ELSE 0 THEN ;
03:58:58
##forth
<cleobuline>
forthBot: 5 test .
03:58:58
##forth
<forthBot>
-1
03:59:15
##forth
<cleobuline>
forthBot: : minop OVER >R 2DUP > test >R XOR R> AND R> XOR ;
03:59:37
##forth
<cleobuline>
forthBot: 2 3 minop
03:59:41
##forth
<cleobuline>
forthBot: .
03:59:41
##forth
<forthBot>
1
04:00:01
##forth
<cleobuline>
forthBot: 3 2 minop
04:00:04
##forth
<cleobuline>
forthBot: .
04:00:04
##forth
<forthBot>
1
04:04:03
##forth
<tabemann_>
lf94: 0 and -1
04:04:16
##forth
<tabemann_>
bit@ always returns a boolean, and booleans in Forth are 0 and -1
04:04:25
##forth
<lf94>
niice!
04:04:29
##forth
<lf94>
ok cool thank you :D
04:04:45
##forth
<lf94>
I'm writing a program for an electronic keyer for morse code
04:04:54
##forth
<lf94>
i'll be sure to send you a video after :)
04:05:31
##forth
<lf94>
tabemann_: my second question would be: am I setting up interrupts correctly
04:06:35
##forth
<tabemann_>
just so you know, you're not defining CONSTANT's right
04:06:51
##forth
<tabemann_>
you define, say, a constant foo to be $FFFF as:
04:06:55
##forth
<tabemann_>
$FFFF constant foo
04:07:13
##forth
<tabemann_>
i.e. the value goes before the word CONSTANT
04:08:28
##forth
<tabemann_>
also, VECTOR! takes an exception vector index, *not* an IRQ index
04:09:09
##forth
<tabemann_>
a vector index is an IRQ index plus 16
04:10:04
##forth
<tabemann_>
also, you don't need OR! and INVERT ... AND!
04:10:13
##forth
<tabemann_>
OR! is already implemented as BIS!
04:10:23
##forth
<tabemann_>
and INVERT ... AND! is already implemented as BIC!
04:10:57
##forth
<tabemann_>
also, START has to be defined *before* TURNKEY
04:11:45
##forth
<tabemann_>
remember that in Forth you can only refer to things declared before itself; if you want to refer to something defined afterwards you have to declare it beforehand with DEFER and then set it later with IS -- but in this case simply switching their order would suffice
04:14:05
##forth
<lf94>
haha thanks. yeah it's been a minute since i wrote forth and I always tend to f up the constants :D
04:14:45
##forth
<lf94>
tabemann_: oh shit thank you for BIS and BIC!
04:15:05
##forth
<lf94>
this is awesome help
04:15:10
##forth
<tabemann_>
they stand for "BIt Set" and "BIt Clear"
04:15:16
##forth
<lf94>
I figured hehe
04:15:40
##forth
<tabemann_>
note that ! is part of the name
04:15:46
##forth
<tabemann_>
BIS! and BIC!
04:15:59
##forth
<lf94>
Right, usually used to indicate "store"
04:16:17
##forth
<lf94>
My Forth memory is a bit fuzzy but it's not entirely gone heh
04:16:29
##forth
<lf94>
It's been about... 5? months
04:16:42
##forth
<MrMobius>
cleobuline: 1 is true in C but it should be -1 in Forth
04:16:55
##forth
<cleobuline>
ok
04:16:56
##forth
<lf94>
I should really write a Forth linter in Forth
04:17:06
##forth
<lf94>
To catch simple stuff like constants being wrong
04:17:28
##forth
<tabemann_>
TRUE being -1 enables not having separate 'bit' and 'logical' operations as C has
04:17:49
##forth
<cleobuline>
forthBot: QUIT
04:17:50
##forth
<forthBot>
Environment for cleobuline has been freed.
04:17:56
##forth
<cleobuline>
forthBot: WORDS
04:17:56
##forth
<forthBot>
USERNAME .S . + - * / MOD DUP DROP SWAP OVER ROT >R R> R@ R@UL R!UL = < > AND OR NOT XOR & | ^ ~ << >> CR EMIT VARIABLE @ ! +! DO LOOP I WORDS LOAD CREATE ALLOT ." CLOCK BEGIN WHILE REPEAT AGAIN SQRT UNLOOP +LOOP PICK CLEAR-STACK PRINT NUM-TO-BIN PRIME? FORGET STRING S" "S 2DROP IMAGE TEMP-IMAGE CLEAR-STRINGS DELAY EXIT CONSTANT MICRO MILLI ROLL DEPTH APPEND MOON-PHASE MOON-RISE-SET
04:18:01
##forth
<lf94>
tabemann_: beautiful.
04:18:13
##forth
<lf94>
tabemann_: is BIS! and BIC! part of forth standard?
04:18:13
##forth
<tabemann_>
old figFORTH's though had 1 for TRUE IIRC, but it's generally considered to not have been a win
04:18:16
##forth
<cleobuline>
AND OR NOT XOR & | ^ ~ << >>
04:18:43
##forth
<cleobuline>
in forthBot yu have c like bit operators
04:19:13
##forth
<lf94>
tabemann_: how do I setup a proper interrupt then btw?
04:19:57
##forth
<tabemann_>
lf94: not to my knowledge -- zeptoforth's BIS! and BIC! were taken from Mecrisp-Stellaris, and IMHO ought to have been in ANS Forth
04:20:26
##forth
<tabemann_>
lf94: your interrupt setup was almost right
04:20:49
##forth
<tabemann_>
you just have to use the IRQ 16 + to get the vector, and when servicing the interrupts you have to clear them
04:21:10
##forth
<lf94>
Is there no simpler way? Would I have then struggled for a bit around this?
04:21:36
##forth
<lf94>
Where would I have learned about the 16 + ?
04:21:51
##forth
<tabemann_>
e.g. 8 INTR_GPIO_EDGE_HIGH! clears the edge high interrupt for GPIO 8
04:21:56
##forth
<lf94>
I know it's not Zeptoforth's reponsibility to teach this, but it couldbe good in the documentation...
04:22:38
##forth
<tabemann_>
lf94: from the ARM Cortex-M0 and ARM Cortex-M33 reference manuals
04:23:06
##forth
<lf94>
:D.
04:23:25
##forth
<lf94>
Would you accept a small documentation addition mentioning this? :)
04:23:32
##forth
<lf94>
I'll open a PR
04:23:51
##forth
<tabemann_>
if you make a PR make it against the 'devel' branch
04:24:01
##forth
<lf94>
Also your project is absolutely amazing. I was wondering if you accept monetary donations
04:24:42
##forth
<tabemann_>
the key thing to remember is that there's vectors for which there are no IRQ's, such as PendSV
04:24:57
##forth
<tabemann_>
and these vectors are those lower than 16
04:25:10
##forth
<lf94>
Ahhh.
04:25:31
##forth
<tabemann_>
oh, no donations are needed (at one point I did consider starting one of those buy-me-a-beer/buy-me-a-coffee things but decided against it)
04:25:56
##forth
<lf94>
The project is just so well done I feel youve given a real gift to the world
04:26:24
##forth
<lf94>
And it has a good chance of living for a long, long time
04:26:32
##forth
<tabemann_>
really, just the fact that people use it and get something out of it makes me happy
04:26:42
##forth
<lf94>
Considering RP2040 and RP2350 will be produced in the hundreds of millions
04:27:55
##forth
<tabemann_>
lately I've been working on PicoCalc support; I don't have my PicoCalc yet but have been using an ST7789V and a couple speakers and driver boards I own to emulate much of the functionality of a PicoCalc
04:29:00
##forth
<lf94>
Wow crazy you mention this, I saw this just the other day too
04:29:03
##forth
<lf94>
It's a cute little device
04:29:12
##forth
<tabemann_>
(I also integrated a keyboard emulation mode because I don't have a PicoCalc keyboard on hand)
04:29:45
##forth
<tabemann_>
I ordered mine on April 20th and was told last week that mine would be amongst a shipment sent to the shipping company yesterday
04:31:38
##forth
<lf94>
This could be a cool device to make games for in forth
04:31:53
##forth
<lf94>
right on the device, that can be reprogrammed in real time
04:31:59
##forth
<tabemann_>
I got one specifically to be a portable Forth machine
04:32:05
##forth
<lf94>
I guess the Python support can do the same
04:32:11
##forth
<lf94>
I figured :p
04:32:40
##forth
<lf94>
Question @ interrupts: so there are 16 interrupts with no configuration?
04:32:49
##forth
<lf94>
(0 through 15)
04:32:57
##forth
<lf94>
So that's why we need to 16 + right?
04:33:33
##forth
<tabemann_>
yeah
04:33:53
##forth
<tabemann_>
actually 15 though, because vector 0 is actually the initial stack pointer
04:34:12
##forth
<tabemann_>
which is used on bootup by the ARM architecture
04:34:18
##forth
<lf94>
ah
04:34:34
##forth
<tabemann_>
note that these can be configured, but aren't configured with NVIC
04:34:58
##forth
<tabemann_>
e.g. many of these interrupts can have their priority set, but not all of them
04:35:24
##forth
<tabemann_>
some of them have priorities fixed in hardware (e.g. Hard Fault)
04:36:07
##forth
<lf94>
Right. The only experience I have with interrupts is on the Nintendo Game Boy and I recall there is a similar system
04:36:28
##forth
<lf94>
You can go to a fixed number of "reset vectors" with "RST I" where I is the number
04:36:39
##forth
<lf94>
Otherwise you enable/disable "standard" interrupts
04:38:13
##forth
<tabemann_>
likewise, you can't disable the hard fault exception handler
04:39:46
##forth
<tabemann_>
CPSID/CPSIE has no effect on it
04:49:23
##forth
<tabemann>
the biggest thing to remember about interrupts is you always have to clear the condition that caused the interrupt or otherwise you will enter an infinite loop, with the interrupt handler being called forever
04:49:39
##forth
<lf94>
Oh, I was reading that say, timer interrupts, clear themselves?
04:51:24
##forth
<lf94>
Is there a better name for these exception vector interrupts
04:51:34
##forth
<lf94>
Instead of IRQ_XXX ?
04:51:53
##forth
<lf94>
Maybe VEIRQ?
04:51:58
##forth
<lf94>
erm, EVIRQ
04:53:02
##forth
<tabemann>
no, you have to clear timer interrupts by setting INTR (note that my TIMER::CLEAR-ALARM-INT also clears any pending timer interrupt)
04:53:53
##forth
<tabemann>
I would just do <your IRQ number> constant foo-irq and the vector being foo-irq 16 + constant foo-vector
04:54:54
##forth
<lf94>
ah ok.
04:56:23
##forth
<MrMobius>
cleobuline: you can have separate bitwise and logical operations but that is also not how other Forths do it
04:56:55
##forth
<MrMobius>
not that you have to do it like everyone else but if you want your bot to be more or less standard, you'll need to do it how most other forths do
04:57:17
##forth
<tabemann>
separate bitwise and logical operations are definitely not traditional in the Forth world
04:57:43
##forth
<tabemann>
and I don't just mean that they're not separate in ANS, but rather that Forths across the board separate the two
04:57:54
##forth
<tabemann>
*don't separate the two
04:59:18
##forth
<tabemann>
Forths normally just have AND, OR, XOR, and what in ANS is INVERT but where I personally prefer NOT
04:59:58
##forth
<lf94>
tabemann: what is force btw?
05:00:39
##forth
<tabemann>
(ANS INVERT is a design-by-committee naming because the ANS people couldn't choose between figFORTH NOT, which acted like C !, and Forth 83 NOT, which acted like what became ANS INVERT)
05:00:55
##forth
<tabemann>
lf94, what do you mean?
05:01:11
##forth
<lf94>
There's a few functions in gpio.fs that take a "force" or output a "force"
05:03:13
##forth
<tabemann>
"force" in that context is basically manually triggering an interrupt in software (when setting it) or getting whether an interrupt has been triggered in software (when getting it)
05:03:26
##forth
<tabemann>
it's not really something you normally have to concern yourself with
05:07:44
##forth
<lf94>
oh nice!
05:07:50
##forth
<lf94>
could be useful :)
05:20:28
##forth
<lf94>
clear-alarm stops the alarm right?
05:21:28
##forth
<tabemann>
CLEAR-ALARM clears the armed alarm, CLEAR-ALARM-INT stops the triggered alarm interrupt and any pending interrupt
05:22:56
##forth
<tabemann>
oh, btw, there is one other thing about your code -- you don't set your GPIO's as inputs or as pull-up's or pull-down's (note that internal pull-downs are borked on the RP2350, and need either external pull-downs or a hack that isn't suitable to what you're doing)
05:30:04
##forth
<lf94>
Why are internal pulldowns broken on rp2350? :s
05:31:46
##forth
<tabemann>
the company the RPi people farmed out the GPIO pad development took a small request to slightly change the pads and completely redesigned them, incorrectly, and I gather the way they were implemented was such that it wasn't caught by the RPi people's own testing
05:33:53
##forth
<lf94>
that's crazy right?
05:34:10
##forth
<lf94>
from what I know most internal pull downs in microcontrollers are...standard to have
05:34:44
##forth
<tabemann>
the hack is to switch on input enable right before reading them, and then disabling input enable right after reading
05:34:48
##forth
<lf94>
I think I need pull-up for this
05:36:07
##forth
<lf94>
So I think I'm almost done alreday
05:39:09
##forth
<lf94>
there is one problem other than the pull-up/down/input missing: is the way I set a timer correct? can I reference the func that's setting it?
05:40:30
##forth
<lf94>
I forgot the '
05:40:39
##forth
<lf94>
to make it into an xt
05:42:29
##forth
<tabemann>
CLEAR-ALARM-INT takes an alarm index
05:42:43
##forth
<tabemann>
and you mean ['] here
05:43:05
##forth
<tabemann>
to reference the func that is setting it to
05:43:12
##forth
<tabemann>
use DEFER
05:43:14
##forth
<tabemann>
like
05:43:27
##forth
<tabemann>
DEFER FOO-ALARM-HANDLER
05:43:29
##forth
<tabemann>
:NONAME
05:43:37
##forth
<lf94>
ahhh yes defer
05:43:38
##forth
<tabemann>
FOO-ALARM CLEAR-ALARM-INT
05:44:01
##forth
<lf94>
I really can't just use ['] ?
05:44:16
##forth
<lf94>
oh whoops @ clear-alarm-int
05:44:33
##forth
<tabemann>
you can't just use ['] alone
05:44:43
##forth
<lf94>
ah.
05:44:46
##forth
<lf94>
defer it is!
05:45:06
##forth
<tabemann>
also, the alarm is set to a specific microsecond explicitly
05:45:49
##forth
<lf94>
oh shit right
05:46:04
##forth
<lf94>
It has to be <internal counter> + N right?
05:46:15
##forth
<tabemann>
so you have to do US-COUNTER-LSB YOUR-US-INTERVAL + ['] YOUR-HANDLER YOUR-ALARM-INDEX SET-ALARM
05:46:37
##forth
<tabemann>
and with defer, e.g., to make an infinite loop that will explode the stack do
05:46:39
##forth
<tabemann>
DEFER FOO
05:46:49
##forth
<tabemann>
:NONAME FOO ; IS FOO
05:49:00
##forth
<lf94>
yessir
05:49:18
##forth
<lf94>
lol
05:49:48
##forth
<lf94>
to _not_ explode the stack I do: defer foo\n :noname ( stuff here ) ; is foo - right?
05:50:01
##forth
<tabemann>
yeah
05:52:30
##forth
<lf94>
On second thought I think I do need pull-down
05:52:47
##forth
<lf94>
when one side of the paddle goes down, it should pull a pin to ground
05:53:16
##forth
<tabemann>
no
05:53:23
##forth
<tabemann>
just tie the other end of the paddle to GND
05:53:27
##forth
<tabemann>
and do a pull-up
05:53:42
##forth
<tabemann>
so when the paddle goes down, the GPIO will go low
05:53:47
##forth
<lf94>
I'm tying it to the rp2040's gnd
05:53:55
##forth
<lf94>
yea
05:53:57
##forth
<lf94>
that's what I meant
05:53:57
##forth
<tabemann>
yeah
05:54:03
##forth
<lf94>
oh that's a pull up
05:54:21
##forth
<tabemann>
pull down is the opposite
05:54:29
##forth
<lf94>
sorry i was thinking literally what you described
05:54:37
##forth
<lf94>
but i find the configuration naming weird lol
05:54:52
##forth
<tabemann>
pull down is when you pull the GPIO low and tie the other end to VCC
05:55:03
##forth
<tabemann>
so when the circuit is closed it goes high
05:55:36
##forth
<lf94>
ah it's from the framing of the gpio being pulled, right.
05:56:04
##forth
<tabemann>
btw, unless you need internal pulldowns or floating pins I would suggest an RP2350
05:56:19
##forth
<tabemann>
even at a lower clock it is faster than the RP2040 and it has gobs more SRAM
05:56:35
##forth
<tabemann>
it also has hardware single-precision floating point
05:56:38
##forth
<lf94>
I'm using a cute little RP2040 USB thing from Aliexpress
05:56:57
##forth
<lf94>
they are quite cheap
05:57:45
##forth
<lf94>
I've used Zeptoforth with it before ;)
05:57:53
##forth
<lf94>
I may have shown you on Discord
05:58:11
##forth
<lf94>
I hooked it up to a PS4 controller and made it control it like a macro system
05:58:21
##forth
<tabemann>
yeah, I remember that
05:58:25
##forth
<lf94>
That was the last time I touched forth lol
05:59:30
##forth
<tabemann>
I should note that RP2350 boards are (almost) as cheap as RP2040 boards
06:01:00
##forth
<lf94>
Yeah I'll probably start buying those instead
06:01:07
##forth
<lf94>
This USB form factor those is really, _really_ nice.
06:01:15
##forth
<lf94>
though*
06:01:32
##forth
<tabemann>
I wouldn't be surprised if you could find something similar running an RP2350
06:02:39
##forth
<lf94>
They are so convenient to hack with
06:02:48
##forth
<lf94>
no cable is really nice
06:05:29
##forth
<tabemann>
my normal way of doing things is to solder pins onto a board, plug it into a little breadboard, and then plug jumper cables into the breadboard
06:06:41
##forth
<lf94>
PULL_UP GPIO_MINE GPIO_CTRL_INOVER! look right?
06:07:20
##forth
<lf94>
Heh. I like to be able to slap in the uC, program the forth to manipulate external hardware objects, and hit the ground running. :D
06:07:24
##forth
<tabemann>
no
06:07:40
##forth
<tabemann>
TRUE GPIO_MODE PADS_BANK0_PUE!
06:07:46
##forth
<tabemann>
*GPIO_MINE
06:07:53
##forth
<lf94>
Oh damn, way off.
06:07:53
##forth
<tabemann>
TRUE GPIO_MINE PADS_BANK0_PUE!
06:08:29
##forth
<lf94>
I shouldve simply searched 'pull up'
06:08:37
##forth
<lf94>
I was too busy searching "PULL_UP" lol
06:09:42
##forth
<tabemann>
you'll also need TRUE GPIO_MINE PADS_BANK0_OD! and TRUE GPIO_MINE PADS_BANK0_IE!
06:10:12
##forth
<tabemann>
if you're using an RP2350 you'll also need at the end FALSE GPIO_MINE PADS_BANK0_ISO!
06:10:16
##forth
<lf94>
Is OD really necessary?
06:10:19
##forth
<tabemann>
however there's an easier way to do this
06:10:23
##forth
<tabemann>
yeah
06:10:28
##forth
<lf94>
I don't think I'd ever accidentally output
06:10:41
##forth
<tabemann>
you need output disable if you're doing things this way
06:10:43
##forth
<tabemann>
however
06:10:46
##forth
<tabemann>
you can just use:
06:10:54
##forth
<tabemann>
PIN INPUT
06:11:00
##forth
<lf94>
Ah the pin interface
06:11:01
##forth
<tabemann>
GPIO_MINE INPUT-PIN
06:11:09
##forth
<tabemann>
GPIO_MINE PULL-UP-PIN
06:11:12
##forth
<lf94>
To be honest I like being exposed a bit to this lower level interface
06:11:20
##forth
<lf94>
I'm learning a lot
06:12:06
##forth
<lf94>
I dont understand though why I need output disabled still
06:12:11
##forth
<lf94>
If I never output
06:12:14
##forth
<tabemann>
the thing that will trip you up if you switch to the RP2350 is PADS_BANK0_ISO!
06:12:37
##forth
<lf94>
Right, but I should "just know that", shouldn't I?
06:12:43
##forth
<lf94>
How are the C folks smoothing that out?
06:12:50
##forth
<tabemann>
if you're using a GPIO like a normal GPIO both OD and IE must be both TRUE or both FALSE at once
06:13:03
##forth
<lf94>
Ah ok.
06:13:10
##forth
<lf94>
Otherwise it's undefined behavior?
06:13:32
##forth
<tabemann>
if you're using it as something other than a normal GPIO, though, it's different
06:14:09
##forth
<tabemann>
if you're using it as an alternate function you need to set OD to FALSE and IE to TRUE
06:14:34
##forth
<lf94>
Ah right this stuff is coming back to me slowly
06:14:39
##forth
<lf94>
I remember reading about this when doing the PS4 controller thing
06:14:53
##forth
<tabemann>
also, if you're using an RP2350 you should set ISO to TRUE before you change these things and then to FALSE afterwards
06:15:00
##forth
<lf94>
Right right.
06:15:06
##forth
<tabemann>
this is a new feature with the RP2350 to avoid, well, glitchiness
06:15:40
##forth
<lf94>
sounds so broken
06:15:47
##forth
<tabemann>
nah
06:15:48
##forth
<lf94>
makes me want to avoid the rp2350 entirely lol
06:15:54
##forth
<tabemann>
it's the opposite
06:16:05
##forth
<tabemann>
the glitchiness is because IE and OD can't be written in the same instruction
06:16:38
##forth
<tabemann>
ISO makes it so that the GPIO does nothing while it is TRUE
06:16:50
##forth
<tabemann>
so you can safely do whatever you want with its configuration without second thoughts
06:17:02
##forth
<tabemann>
the RP2040 doesn't have this
06:17:17
##forth
<lf94>
Ah.
06:17:18
##forth
<tabemann>
so you have to take a bit more care when changing GPIO pad settins with the RP2040
06:17:25
##forth
<lf94>
Ok that framing makes it better
06:17:48
##forth
<lf94>
Think it's done
06:17:55
##forth
<lf94>
I'll see probably tomorrow lol
06:17:56
##forth
<forthBot>
Environment for cleobuline inactive, freeing...
06:18:55
##forth
<tabemann>
oh, characters can't be specified with 'x'
06:19:10
##forth
<tabemann>
e.g. to get a character literal for the letter x you do [CHAR] x
06:19:28
##forth
<lf94>
gforth lied to me
06:19:30
##forth
<lf94>
:p
06:19:36
##forth
<lf94>
(gforth let me do that)
06:20:23
##forth
<tabemann>
SET-ALARM requires an alarm index
06:20:41
##forth
<tabemann>
alarm indices are from 0-3
06:20:51
##forth
<tabemann>
( us xt index -- )
06:21:23
##forth
<lf94>
blah
06:21:39
##forth
<tabemann>
also you don't need: ALARM_PROCESS_PADDLE alarm-set? if exit then
06:21:47
##forth
<lf94>
I do
06:22:03
##forth
<lf94>
I have a full flowchart you havent seen yet
06:22:11
##forth
<lf94>
requires to check if a timer is already on
06:22:33
##forth
<lf94>
I think maybe its placement may be bad
06:22:49
##forth
<tabemann>
paddle.on.left VECTOR_LEFT vector!
06:22:49
##forth
<tabemann>
paddle.on.right VECTOR_RIGHT vector!
06:22:57
##forth
<lf94>
Yeah, the placement is bad
06:23:03
##forth
<lf94>
my defer needs to live higher up too
06:23:05
##forth
<tabemann>
should have ['] paddle.on.left
06:23:11
##forth
<lf94>
oop! nice
06:23:12
##forth
<tabemann>
and ['] paddle.on.right
06:23:18
##forth
<tabemann>
no your defer is fine
06:23:41
##forth
<tabemann>
also you don't need to define TRUE and FALSE -- they're already defined
06:23:56
##forth
<lf94>
no there are 2 other calls to on.timer that are higher than it
06:24:05
##forth
<lf94>
yeah I know I was being silly with that one :p
06:24:07
##forth
<tabemann>
oh gotcha
06:24:17
##forth
<lf94>
gonna update the gist
06:24:20
##forth
<lf94>
2 sec
06:25:36
##forth
<lf94>
Same URL, refresh
06:26:11
##forth
<tabemann>
oh NVIC_ISER_SETENA! takes an IRQ index and not a vector index
06:28:39
##forth
<tabemann>
oh and one biggie
06:29:00
##forth
<lf94>
=_=
06:29:08
##forth
<lf94>
Do I need a different word then?
06:29:18
##forth
<tabemann>
there is only one GPIO interrupt per CPU core that is shared between all GPIO's
06:29:21
##forth
<tabemann>
on the RP2040
06:29:49
##forth
<tabemann>
actually, it isn't a per CPU core interrupt, from checking the refman again
06:30:00
##forth
<tabemann>
it's IRQ 13
06:30:21
##forth
<tabemann>
so vector 29
06:30:41
##forth
<tabemann>
IO_IRQ_BANK0 that is
06:31:18
##forth
<lf94>
-> only one gpio interrupt per cpu core <- what's wrong with that
06:32:25
##forth
<tabemann>
you're using two interrupts, one for each GPIO you're reading
06:32:46
##forth
<tabemann>
and also you're using IRQ's 0 and 1 for them, which are actually timer interrupts
06:33:28
##forth
<lf94>
I'm using 0 16 + and 1 16 +
06:33:32
##forth
<tabemann>
you should be just listening to IRQ 13 and servicing both paddles in one interrupt handler
06:33:49
##forth
<tabemann>
the 16 + turns an IRQ into a vector index
06:33:54
##forth
<lf94>
How can I differentiate the paddles ?
06:34:25
##forth
<tabemann>
you check the GPIO's separately in the same interrupt handler
06:34:59
##forth
<tabemann>
all GPIO's use the same IRQ and the same interrupt vector
06:35:15
##forth
<lf94>
Which is 13
06:35:26
##forth
<lf94>
Ok ok ok, nice.
06:35:42
##forth
<lf94>
I understand what you're saying now. That's a little odd I'd say, but maybe not surprising
06:36:20
##forth
<tabemann>
you always have to check the GPIO's to make sure they have triggered the right things inside the interrupt handler anyways
06:36:46
##forth
<tabemann>
and you do do that, except you frob the alarms regardless of their actual trigger state
06:40:57
##forth
<lf94>
I'd be so screwed without you helping me
06:41:17
##forth
<lf94>
How the hell did I do the ps4 thing so easily
06:41:31
##forth
<lf94>
Maybe I ended up using the pin interface you wrote
06:41:40
##forth
<lf94>
and it was only output
06:42:20
##forth
<tabemann>
dealing with interrupts is definitely harder than just doing output with PIN
06:43:26
##forth
<lf94>
You mentioned I'd have to clear the interrupt flag, but wouldn't that only be true for interrupts triggered by LEVEL_* ?
06:43:35
##forth
<lf94>
(and timer I guess)
06:43:45
##forth
<tabemann>
no, you have to clear it regardless
06:44:01
##forth
<lf94>
ah, no I guess not - right. they are like "please process the interrupt request" but they will stay as 1
06:44:05
##forth
<lf94>
if not cleared
06:44:07
##forth
<lf94>
gotchya
06:45:52
##forth
<tabemann>
the general rule with exceptions is you always have to clear the condition that triggered the interrupt or otherwise you'll loop forever
06:47:00
##forth
<tabemann>
the only exception are interrupts like SysTick, PendSV, and SVC
06:47:07
##forth
<tabemann>
*the main exceptions
06:53:01
##forth
<lf94>
Is there no constant for IO_IRQ_BANK0 ?
06:53:23
##forth
<lf94>
Oh found it
06:53:33
##forth
<lf94>
or not
06:53:37
##forth
<lf94>
Only in RP2350
06:54:28
##forth
<tabemann>
yeah, I just noticed that
06:54:32
##forth
<tabemann>
an oversight on my part
06:57:23
##forth
<tabemann>
just added it in the source code, will be in the next release
06:59:34
##forth
<lf94>
ok I think igot it
07:00:22
##forth
<lf94>
oh whoops
07:00:25
##forth
<tabemann>
13 constant IO_IRQ_BANK0 13 should be just 13 constant IO_IRQ_BANK0
07:00:44
##forth
<lf94>
sorry yea copypasta
07:00:49
##forth
<lf94>
VECTOR_LEFT/RIGHT gotta go too
07:02:19
##forth
<tabemann>
VECTOR_LEFT, e.g., should be GPIO_PADDLE_LEFT
07:02:32
##forth
<tabemann>
same with VECTOR_RIGHT and GPIO_PADDLE_RIGHT
07:02:33
##forth
<lf94>
updated
07:02:36
##forth
<lf94>
yep yep got it B)
07:02:48
##forth
<lf94>
it's all making sense now
07:03:09
##forth
<tabemann>
also, you're doing:
07:03:10
##forth
<tabemann>
ALARM_PROCESS_PADDLE alarm-set? if exit then
07:03:10
##forth
<tabemann>
paddle.on.timer
07:03:12
##forth
<tabemann>
twice
07:04:02
##forth
<lf94>
Oh right because they arent separate anymore
07:04:17
##forth
<lf94>
actually on my god _yes_
07:04:22
##forth
<lf94>
cleans it right up
07:04:49
##forth
<lf94>
updated
07:05:41
##forth
<tabemann>
one other thing, just as a matter of course, I would check the conditions and only trigger that code if at least one of them was true
07:06:00
##forth
<tabemann>
the reason is that if in the future you ever wanted to trigger separately on another GPIO
07:06:09
##forth
<tabemann>
you might not want to call that code
07:06:30
##forth
<lf94>
am I not doing that?
07:06:51
##forth
<tabemann>
you're calling that code whenever the IO_IRQ_BANK0 handler gets called
07:06:56
##forth
<lf94>
Right
07:07:24
##forth
<lf94>
I have conditions in all those routines though
07:07:59
##forth
<tabemann>
I suppose it's not necessary
07:07:59
##forth
<lf94>
(I think Im misunderstanding what you're getting at)
07:08:15
##forth
<lf94>
You want me to "lift" the conditions higher I'm guessing?
07:10:15
##forth
<tabemann>
what I mean is I'd only call paddle.on.timer if at least one of the edge conditions was true
07:10:42
##forth
<lf94>
Ohhh
07:10:55
##forth
<lf94>
...yes, that was the intent. excellent catch
07:11:04
##forth
<tabemann>
it's not truly necessary as IO_IRQ_BANK0 *should* only be called if at least one of them are true in this particular code example
07:11:20
##forth
<tabemann>
but if you ever want to listen to another GPIO as well it would become necessary
07:11:21
##forth
<lf94>
I swear man, you're amazing programming
07:11:23
##forth
<lf94>
programmer
07:11:25
##forth
<lf94>
I'm so tired
07:11:37
##forth
<lf94>
ah right
07:11:41
##forth
<lf94>
but still
07:12:06
##forth
<lf94>
you're right this doesn't actually intentionally encode I only want that to fire if any of those 4 edge conditions are true.
07:12:15
##forth
<lf94>
I'll fix it
07:15:25
##forth
<lf94>
I love forth
07:15:35
##forth
<lf94>
update
07:15:54
##forth
<lf94>
so beautifully added
07:16:56
##forth
<tabemann>
okay, you don't need those extra TRUE's
07:17:22
##forth
<tabemann>
because you've already got those DUP's
07:17:34
##forth
<lf94>
heh you caught me before i removed them ;p
07:17:45
##forth
<tabemann>
and anyways, if you didn't use DUP's and you used TRUE's you'd also need to add ELSE FALSE THEN's as well
07:17:45
##forth
<lf94>
f5
07:18:27
##forth
<lf94>
yea they were part of an earlier moment - im really really tired heh.
07:19:13
##forth
<lf94>
you could probably test this with your own rp2040 easily
07:19:40
##forth
<lf94>
I'm not at home, but I brought a paper clip with me
07:19:55
##forth
<lf94>
to tap gnd and the proper gpio
07:20:02
##forth
<lf94>
To trigger stuff
07:21:18
##forth
<tabemann>
I'm getting tired too; I'm going to call it a night shortly
07:22:41
##forth
<lf94>
heh, sounds good. thank you again for all your help.
07:23:41
##forth
<tabemann>
oh no problem
07:23:44
##forth
<tabemann>
g'night!
13:08:07
##forth
<cleobuline>
forthBot: S" Patricia qui prend son petit dejeuner avec des tartines "S IMAGE
13:08:59
##forth
<cleobuline>
good morning
15:08:23
##forth
<forthBot>
Environment for cleobuline inactive, freeing...
16:09:47
##forth
<lf94>
morning!
16:09:51
##forth
<lf94>
Time to test this out
16:37:30
##forth
<tabemann>
back
16:37:33
##forth
<tabemann>
hey lf94
16:45:14
##forth
<lf94>
morning tabemann !
16:45:18
##forth
<lf94>
I havent started yet
16:45:24
##forth
<lf94>
ate breakfast first
16:45:59
##forth
<lf94>
I forget how to upload zeptoforth programs to the rp2040
16:46:05
##forth
<lf94>
It was pretty easy
16:46:32
##forth
<lf94>
dont tell me - reviewing the docs :)
16:46:44
##forth
<lf94>
I want to do a PR after on where I had trouble and add to the docs
16:55:54
##forth
<lf94>
Ah right, picocom, eth4com, etc...
16:56:07
##forth
<lf94>
e4th
16:57:10
##forth
<lf94>
Haha, nice. So yeah this RP2040 already has Zeptoforth from my last project
16:57:13
##forth
<lf94>
> Built for rp2040, version 1.10.0, on Sat Feb 8 12:10:34 PM CST 2025
16:57:33
##forth
<lf94>
It really has been 4 months then since my last Forth hacking
16:59:10
##forth
<lf94>
Surface README doesn't remind me how to push entire forth files
16:59:57
##forth
<lf94>
> codeload3.sh
16:59:59
##forth
<lf94>
:o
17:05:03
##forth
<lf94>
Yep got it, amazing
17:05:14
##forth
<lf94>
Would be useful to have that more prominent
17:05:41
##forth
<lf94>
How the heck do you include modules?
17:05:45
##forth
<lf94>
Trying to include gpio.fs
17:08:10
##forth
<lf94>
ah just "import"
17:08:28
##forth
<tabemann>
back
17:09:09
##forth
<lf94>
I keep getting stack underflow lol
17:09:48
##forth
<tabemann>
no, it's:
17:09:50
##forth
<tabemann>
gpio import
17:09:59
##forth
<tabemann>
gpio isn't a file you're including
17:10:02
##forth
<tabemann>
this isn't C
17:10:22
##forth
<tabemann>
rather it is a wordlist/module you are importing into the current search order
17:10:36
##forth
<tabemann>
and I suggest you reboot at this point
17:10:39
##forth
<lf94>
Agh sorry. It's been a bit
17:10:44
##forth
<lf94>
Gotchya, will o
17:10:46
##forth
<lf94>
do
17:11:01
##forth
<lf94>
import gpio made sense to me because I thought `import` was a parse word
17:11:13
##forth
<tabemann>
no, GPIO is a constant
17:11:23
##forth
<tabemann>
whose value is a wordlist/module ID
17:11:58
##forth
<lf94>
ahhh :)
17:12:07
##forth
<lf94>
thinking too filesystem x)
17:12:10
##forth
<lf94>
> unable to parse: alarm-set?
17:12:17
##forth
<lf94>
I guess this isnt the correct word
17:12:31
##forth
<tabemann>
you also need: timer import
17:12:35
##forth
<lf94>
oh!
17:12:37
##forth
<lf94>
right!
17:12:54
##forth
<lf94>
sorry lol I feel like I'm annoying you with my mistakes :)
17:13:06
##forth
<tabemann>
also, you'll need: interrupt import
17:13:10
##forth
<lf94>
Nice, it all parsed
17:14:00
##forth
<tabemann>
I suggest you try running START now (TURNKEY only does anything if you've compiled to flash and then rebooted)
17:14:11
##forth
<lf94>
Yea I actually removed turnkey for now
17:15:38
##forth
<lf94>
To be clear, to completely reset the device (bring zepto back to a starting state), I can do restore-state?
17:20:27
##forth
<tabemann>
no
17:20:32
##forth
<tabemann>
do REBOOT
17:21:06
##forth
<tabemann>
RESTORE-STATE erases everything in flash after its 'factory state' and *then* reboots
17:21:27
##forth
<tabemann>
if you just want to erase what you've compiled into RAM REBOOT will suffice
17:22:16
##forth
<lf94>
oh I wanted that, a complete complete restore
17:22:32
##forth
<lf94>
To be sure I had nothing of my previous project on here
17:22:50
##forth
<lf94>
welp grounding pin 8 is not doing anything :')
17:24:02
##forth
<lf94>
I need to go do some Father's day stuff
17:24:33
##forth
<lf94>
ttyl, surely it's something basic
17:26:55
##forth
<tabemann>
one error I always make with RP2040 and RP2350-based boards it to confuse GPIO numbering with pin numbering
17:28:02
##forth
<tabemann>
good luck with your project!
17:49:49
##forth
<tabemann>
hey szilard