Open bmentink opened 3 weeks ago
Never mind, finally found it here: https://github.com/tabemann/zeptoforth/releases/
Couple of quick questions:
turnkey
function, so that you upload code that compiles to flash and then executes on boot. I am struggling to find that in the docs.Many Thanks.
I found the turnkey info in the wiki, so that is great.
Still cannot use zetoforth.js either on your server or on a local server. The connect
button does not pop up a gui to connect to a detected port. Nothing happens. Have you tried this on macos? Thanks.
On Thu, May 9, 2024 at 3:38 PM bmentink @.***> wrote:
I found the turnkey info in the wiki, so that is great.
You caught me just while I was writing a response about that.
Still cannot use zetoforth.js either on your server or on a local server. The connect button does not pop up a gui to connect to a detected port. Nothing happens. Have you tried this on macos? Thanks.
Which web browser are you using? zeptocom.js does not work with Safari or Firefox because it requires the Web Serial API, which is only provided by Chrome, Chromium, or other web browsers derived from them.
Travis
Hi, thanks for the reply. I am using the brave browser, it is based on chromium engine. So it should work. I will try installing chromium itself and see if it is the same..
Ok, just tried the latest stable build of chromium for macos arm64 and it works fine ..
On Thu, May 9, 2024, 17:21 bmentink @.***> wrote:
Ok, just tried the latest stable build of chromium for macos arm64 and it works fine ..
Good to hear!
Travis
On a different topic, where do I find examples of adc handling. I am having trouble for example:
adc import ok
0 26 adc-pin invalid ADC
1 26 adc-pin invalid ADC
2 26 adc-pin invalid ADC
3 26 adc-pin invalid ADC
What is the correct adc for pin26 on rp2040? (There are 3 external adc's pin26,pin27,pin28)
In your docs on the adc, you mention:
On the RP2040 and STM32F411 there is only a single ADC peripheral, numbered 0 on the RP2040
However there is 4 adc channels on the rp2040, so what does the above mean.
(3 external adc's and temperaure)
Okay, adc-pin
on the RP2040 is garbage, don't use it; it was meant only for compatibility with STM32 platforms, but as I never used it, I did not realize it was broken. And even with that in mind, there is only one ADC peripheral on the RP2040 even though there are four ADC channels. Anyways, using the ADC is as simple as:
adc import ok
temp-adc-chan default-adc adc@ . 870 ok
temp-adc-chan default-adc adc@ . 865 ok
temp-adc-chan default-adc adc@ . 866 ok
temp-adc-chan default-adc adc@ . 866 ok
temp-adc-chan default-adc adc@ . 865 ok
temp-adc-chan default-adc adc@ . 865 ok
etc.
where default-adc
is 0 and temp-adc-chan
is 4. (There are four ADC pins shared with GPIO's, corresponding to GPIO's 26 through 29, and a fifth ADC channel that measures the internal temperature.)
Many thanks for that. I did not realise there was a pin29 ADC, what does that read VSYS?
Just quickly on another isssue with pwm's: I have 6 channels pwm working but trying to get an interrupt vector added to slice 0 (or any 0,1,2) I did the following:
: pwm_wrap_int ( -- ) \ interrupt routine
;
......
['] pwm_wrap_int pwm-vector!
%00000001 enable-pwm-int
%00000111 enable-pwm
However, when I do the last line it hangs up the console, have to pysically remove power from the board, not even a reboot get's it working again, what have I done wrong? The above snippet is in a pwm setup word..
What is happening is that you are not calling %00000001 clear-pwm-int
within pwm_wrap_int
so pwm_wrap_int
keeps on getting called in a tight loop forever, such that the USB interrupt handler never gets called so the Reboot button, i.e. Control-C over the console, never is handled.
Travis
Ahh, thanks Travis.
The other bother I have with pwm , is setting the duty with pwm-counter-compare-b! and pwm-counter-compare-a!.
If these channels(a/b) are alternate phases of a top/bottom fet, then controlling the duty for each fet individually, there will be small instants of time where you can get both on at the same time causing shoot-through current. Is there a way to alter the duty of an a/b pair at the same time? I can't see one in your PWM API.
I am doing:
: set-duty ( n - )
dup 0 pwm-counter-compare-b!
dup 0 pwm-counter-compare-a!
dup 1 pwm-counter-compare-b!
dup 1 pwm-counter-compare-a!
dup 2 pwm-counter-compare-b!
2 pwm-counter-compare-a!
;
Thanks, Bernie
No, in my API I did not provide a means for setting both the A and B compare fields at once. However, there is a way of doing it:
: pwm-counter-compare-both! ( b a index -- )
-rot $FFFF and swap 16 lshift or swap pwm::pwm-internal::CH_CC !
;
I have confirmed that the above code compiles, but I have not really tried it out.
Oh, btw, about GPIO pin 29, one thing to remember is not all of the GPIO pins are exposed to the user on the Raspberry Pi Pico, and IIRC that is one of those which are not.
Travis
That worked great, thanks... I had a look at some of the drivers including PWM to understand what you were doing. I love the concept of being able to have modules/sub-modules etc keeps everything very tidy ..
Have you any thoughts about supporting the ADC FIFO? At times it would be useful to trigger conversion of say 3 adc channels then wait on fifo interrupt to read them out all at once. I am doing a hard real-time project (Sensorless BLDC motor control) where there is some time critical things to do every PWM cycle ..
Cheers
On Fri, May 10, 2024 at 3:38 PM bmentink @.***> wrote:
That worked great, thanks... I had a look at some of the drivers including PWM to understand what you were doing. I love the concept of being able to have modules/sub-modules etc keeps everything very tidy ..
Have you any thoughts about supporting the ADC FIFO? At times it would be useful to trigger conversion of say 3 adc channels then wait of fifo interrupt to read them out all at once. I am doing a hard real-time project (Sensorless BLDC motor control) where there is some time critical things to do every PWM cycle ..
Currently I do not support the ADC FIFO, partly because the ADC API is currently essentially a lowest-common-denominator that also covers a number of STM32 microcontrollers (and partly because I have never had any projects which required more advanced control of the ADC). However, there is nothing stopping you from implementing this, especially because the ADC API as currently implemented does not use interrupts and thus would not be broken by writing your own ADC interface which does use the ADC FIFO interrupt. It would probably be better if you implemented it, actually, because you know exactly what your needs are, whereas I would just be guessing, which might not be helpful if you are working on a hard real-time project. Of course, I would be open to including your code in zeptoforth once you are done with it.
Travis
Message ID: @.***>
Thanks, will do ...
Can you help with a macos alternative to "gas"? Macos has "as" for arm64 but I do not know if it cross assembles for other arm cores..
On Fri, May 10, 2024 at 4:47 PM bmentink @.***> wrote:
Thanks, will do ...
Sorry for not offering more, but as you are doing hard real time that is an area where you likely have special needs for what you are doing, particularly if you are doing things on a per-PWM-clock basis.
Travis
Not a problem at all. I am going to have to do some raw adc stuff anyway as your function takes 54us to read a channel. (0 0 adc@ drop)
Did you have any idea's about macos compiling of your code.. i.e gas
equivelent for macos cross-assembly?
On Fri, May 10, 2024 at 7:14 PM bmentink @.***> wrote:
Not a problem at all. Did you have any idea's about macos compiling of your code.. i.e gas equivelent for macos cross-assembly?
This requires the GNU arm-none-eabi toolchain, which is maintained by the people at ARM. I have no expectation that it will compile with any toolchain provided by Apple.
Travis
Message ID: @.***>
Can you pleas tell me where where I can find info on location of gpio interrupt vectors? I do not see any reference to those in gpio.md or gpio.fs .... probably me being blind though ..... an example would be great, thanks.
An example of the GPIO interrupt in action can be found at https://github.com/tabemann/zeptoforth/blob/master/test/rp2040/lmt01_test_ssd1306.fs - note that io-irq
is the IRQ number for the GPIO interrupt, io-vector
is the vector index for the GPIO interrupt, PROC0_INTS_GPIO_EDGE_LOW@
is used for testing for low edge events on core 0, INTR_GPIO_EDGE_LOW!
is used for clearing low edge events, and PROC0_INTE_GPIO_EDGE_LOW!
is used for enabling (and disabling) edge low events on core 0.
Travis
Thanks. Mach appreciated.
By the way, what is the correct way to do init's. I notice you call init
in your drivers, what is the correct way to handle init's at the module level?
Thanks Bernie
On Sun, May 12, 2024, 23:33 bmentink @.***> wrote:
Thanks. Mach appreciated.
By the way, what is the correct way to do init's. I notice you call init in your drivers, what is the correct way to handle init's at the module level?
The best way to do this in new code is to define INIT-FOO or like and do:
: init-foo ( -- ) \ your code here ;
initializer init-foo
This can be anywhere in your code and will work correctly both when compiled to flash and to RAM.
Travis
Thanks. Sorry about all the questions. A couple more :)
I notice in the timer module there is a delay-us
function, does that do a pause
?
Also, not knowing any better, I am continuously doing reboot/connect/send file, as I don't see away to forget
words I am developing. Is there a better way? (I have been using the zeptoforth.js tool for small code snippet testing)
On Mon, May 13, 2024, 17:59 bmentink @.***> wrote:
Thanks. Sorry about all the questions. A couple more :)
I notice in the timer module there is a delay-us function, does that do a pause ?
DELAY-US specifically does not do a PAUSE by design, as it is meant for short, high-resolution delays.
Also, not knowing any better, I am continuously doing reboot/connect/send file, as I don't see away to forget words I am developing. IS there a better way?
zeptoforth does not have FORGET by design (there are reasons for this), even though it has MARKER and CORNERSTONE for the flash dictionary (note that these will reboot the MCU).
Travis
Thanks. Not sure on the rational of marker
and cornerstone
if they involve a reset of the device. The whole idea of forth forget
or marker
is that you can try a piece of code, then remove that code with forget or marker, and then reload, without resetting your machine or loosing connection to the device .. it makes development so much faster ..
(Also, when I develop code, i write code with a marker at the top, then leave it there in ram/flash when I am happy, and go on to developing the next bit of code, with a marker ... so you can do a lot of programming without having to reset)
Is there a reason why your version of marker
reset's the device?
What is the difference between marker
cornerstone
and restore-state
if they all reset the device?
The purpose of marker
and cornerstone
is to enable erasing words that have been compiled into flash selectively. Note that they are specifically for words in flash. The thing is that this puts the device into a potentially undefined state, hence the reset. (For instance, the flash dictionary index, aka the "minidictionary", is invalidated by these operations.)
About restore-state
, that is just a specific word created with cornerstone
than comes with the non-STM32F411 full
builds. You can create your own cornerstones just like it (e.g. I do that if I have compiled code that I would like to preserve in case code I compile code after it which turns out to be bad, so I don't have to load all my code again from scratch.)
ok, so there is no way to erase a group of words compiled into ram without reboot ... that's a shame.
Can you tell me what is your process for development then, is it all compiled into flash? I had assumed that development could be done in ram, then flashed when it all was tested..
On Tue, May 14, 2024 at 10:22 PM bmentink @.***> wrote:
ok, so there is no way to erase a group of words compiled into ram without reboot ... that's a shame.
Can you tell me what is your process for development then, is it all compiled into flash? I had assumed that development could be done in ram, then flashed when it all was tested..
The development process is to first compile my code into RAM (which is the default), rebooting any time I run into an issue, and reloading my code into RAM again. Note that I hadn't thought of adding a FORGET for code in RAM in part because if something fails at this point, I normally treat the system as being in an undefined state, and I reboot to be on the safe side once I am done diagnosing the issue.
Then, once my code is finished, I issue COMPILE-TO-FLASH, compile my code (into flash), adding a CORNERSTONE to allow erasing more code compiled to flash after this code without disturbing this code, and then (this is important, because it is needed to ensure many things are initialized properly) rebooting.
Then I cycle back to my original state of compiling code to RAM to test more code.
Travis
Thanks, totally understand your reasons.
In the past when I have developed into RAM then it if you have code go wrong, it is normally stack underflow issues and you have that fully protected. If I am developing a driver that talks to registers etc and I put the peripheral in a weird state, then sure I would reboot back to a safe state, but that is very rare.
Personally I would add RAM support for marker
so that it does not reboot when you use it, and leave that decision with the user, after all they should know enough to make that decision themselves. That would speed up development greatly.
I assume, that doing that would be less work for you than adding a new word forget
... Cheers Bernie
Thanks for all your help. I have managed to get a BLDC motor working in sensorless mode using zeptoforth. I re-wrote the adc read function, it now executes in 5us instead of 50us, it is good enough if I read one ADC channel per PWM cycle. Ideally I would like to read all three in one PWM cycle by using the ADC fifo and interrupt in continous mode, then just read the results in the PWM. I will look at adding fifo support to the ADC driver.
But the motor works well from 200rpm to over 4000rpm, it is a 100KV motor.
By the way, can any of your existing STM platforms work on the STM32G431 boards?
On Mon, May 20, 2024 at 3:17 AM bmentink @.***> wrote:
Thanks for all your help. I have managed to get a BLDC motor working in sensorless mode using zeptoforth. I re-wrote the adc read function, it now executes in 5us instead of 50us, it is good enough if I read one ADC channel per PWM cycle. Ideally I would like to read all three in one PWM cycle by using the ADC fifo and interrupt in continous mode, then just read the results in the PWM. I will look at adding fifo support to the ADC driver.
But the motor works well from 200rpm to 4000rpm, it is a 100KVa motor.
Good to hear it worked for you!
By the way, can any of your existing STM platforms work on the STM32G431 boards?
I currently do not support any STM32Gxxx platforms at the present, as I have not seen any particular demand for them (so I have been focused for the last couple years on the RP2040, which has had by far the most demand). If you feel like investing the time in a port, though, I would welcome it!
Travis
Message ID: @.***>
HI, I would love to try the recent release of the fullusb version for the rp2040, but I cannot find a link anywhere from this repo. What am I not seeing?
Many Thanks & great work!