Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 11:47 05 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Pico PIO Development

     Page 1 of 4    
Author Message
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 12:59am 19 Aug 2021
Copy link to clipboard 
Print this post

@Mixtel90 - Mick
Thought I'd branch this away from the PicoMite thread. Just for interest, how enthusiastic are you with the development of the PIO assembler for Pico?  It's complicated no doubt, and may be moving to the "back burner" indefinitely?
<<huge chunk deleted>>
I had a problem with some code to generate a divide by 100 (5khz to 50hz test)
First bit of code used a "jmp" statement, second bit of code used the ".wrap"
statement. First code worked perfectly, second worked but no good.
Found the problem was I had not used the:
PIO(EXECCTRL jmp_pin ,wrap_target, wrap) function in the setup!  
Thanks anyway for all your work  
led
edit: edited out the "chunk"
Edited 2021-08-19 12:03 by led-bloon
Miss you George
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 5740
Posted: 08:10am 19 Aug 2021
Copy link to clipboard 
Print this post

Sometimes my enthusiasm wanes... lol
I'm essentially a hardware guy - I always was.

I don't get as much time as I'd like for the PIO assembler. It's mostly done on the three days a week that I go to look after my mum. I get a bit of peace and quiet when she dozes off! While I'm at home I like to play with the hardware stuff like the Backpack. (It's also when I get dragged away by SWMBO for such mundane things as shopping!)

Part of my problem with the assembler is that I've never attempted anything like that before and I've made silly mistakes that I've kept having to go back to sort out. The current version is *much* different to the very early ones in detail as it has a lot of tidying up.

The .wrap and .wrap target directives really confused me at first. The PIO program is only "half a program", if you see what I mean. The state machine registers are the other half. I cut my programming teeth on Z80 machine code (I never even saw an assembler for 6 months and BASIC wasn't available) so that concept took some re-learning for me!

Even now, I'm not sure just how far the assembler should/can actually go. I probably *could* make it so that you only enter the program into PASM and all the registers are filled in automagically, but that looks like *really scary programming*, although I think it would be the ideal for beginners. It's not what the user would see when looking at the Raspberry Pi documentation though, which could be very confusing. Some things can't really be set in the user program easily anyway, they have to be pre-set in the registers. I did consider introducing some new directives to set the necessary flags, but it gets stupidly over-complicated for little gain. Peter has already done them anyway!

The alternative is to let the programmer fill in the registers and just use PASM to produce what will actually go into the program area. That's more or less where it is up to now. IMHO this works reasonably at the moment. I'm trying to get it to work logically when used with Peter's commands. So I make the program array and that's passed to the PIO command. Exactly *how* I do it is what I'm currently working on. Whether PASM should live in the user's program as a set of SUBs or whether it should be in a flash slot. I'm liking the latter as it completely separates it. However I'm having "fun" with the CHAIN command and the dimensioned array.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3558
Posted: 08:42am 19 Aug 2021
Copy link to clipboard 
Print this post

The issue I see with the current approach is that (for example) the .wrap and .wrap_target result from the assembler, as does the compiled code.

To use that in you project, you have to close the assembler, open your program, and copy these values in their respective locations.
The code in PIO PROGRAM and other parameters go to PIO INIT MACHINE through its various "helpers".

It would already help a lot of you could "call" the assembler from your program and use the output directly. That way we coudl also "reserve" the associated pins more or less automatically. Now you need to manually allign the SETPIN commands with whatever you assign the PIO sequencer pins to.

And I dislike defining identical things in 2 different places. When you design something, you remember, but a year later, you never remember where all these definitions must be done.

Those are my 5 cents...

Volhout
PicomiteVGA PETSCII ROBOTS
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 5740
Posted: 09:05am 19 Aug 2021
Copy link to clipboard 
Print this post

.wrap and .wrap target can't go into the memory space. PASM updates EXECCTRL with the addresses of them during assembly automatically. The user then has to use that copy of EXECCTRL when programming.

I'm slowly coming back to the idea that PASM might be better as subroutines. It's just a bit of a pig if you want to add it to an existing program. The current version is basically a "shell" program showing how to use PASM, but also includes a way to save & load a *.PIO file containing the program and register arrays. Having it in the user program makes it very simple for PASM to modify the program and register arrays automatically.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3558
Posted: 10:07am 19 Aug 2021
Copy link to clipboard 
Print this post

In the MX170 MMBasic you have the possibility to add code to the "library". In that case it is not visible in the end user program, but becomes part of the system.

That would be a way to implement PASM in the PICO.
PicomiteVGA PETSCII ROBOTS
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 5740
Posted: 10:51am 19 Aug 2021
Copy link to clipboard 
Print this post

Well, it would if there was a "library"...  :)

That's why I was attempting to use a flash slot and chain PASM.
Of course, DATA statements in the user program aren't passed to the CHAINed one so they have to be kept with PASM.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 10:28pm 19 Aug 2021
Copy link to clipboard 
Print this post

Mick
Currently I have your (modified) assembler program saved in Flash Slot 1.
I now use VAR SAVE pio1%() after the call to PASM to store away the results.
I do not re-save Slot1, but rather copy changes into a text file (saves additional flash save/erase cycles)
My test programs in flash, DIM pio1%(7) and do a VAR RESTORE.
Moving between your program and a test program is fine, as they are being copied into RAM so no great over-use of Flash as in other platforms.
VAR RESTORE will work great with the autorun option, in a final program, too.
led
Edited 2021-08-20 11:50 by led-bloon
Miss you George
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 05:53am 20 Aug 2021
Copy link to clipboard 
Print this post

Mick
Have noticed a slight anomaly in the code, I'm guessing Peter's end.
'setpin' command uses pin numbers 1 - 34 -> great
'PIO (Pinctrl n,n,n,?,?,?)' the three _base values require 0 based values.
(actually the set_base, but I assume the other two as well)
led
Miss you George
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 5740
Posted: 07:14am 20 Aug 2021
Copy link to clipboard 
Print this post

I was messing about with VAR SAVE at one point and couldn't get it to do what I wanted. I must have been doing something wrong. :)

I'll check the RPi docs on pin numbering. I'm not sure if they work from base 0 or 1. One of us will be right. :)

I suspect that pin numbering should really start at 0 (as RPi start at GPIO0), in which case setpin should be working with 0-31 as all the pin registers are 5-bit. e.g. out_base=2, out_count=2 would give you GPIO2 and GPIO3 to play with. Does Set Pin 0 then work from the first pin mapped, i.e. GPIO2 or does it control GPIO0? There's such a lot of this thing that I dont' understand at all yet... :(
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 07:45am 20 Aug 2021
Copy link to clipboard 
Print this post

Peter has (rightly) started with GP0 as pin 1 in code, to line up with all other platforms I think.  See his pinout table:
Pinout table
I think his pinctrl function has to modified likewise.  I think the execctrl may need looking at with the jmp_pin numbering (or is it a mask?). Haven't got that far yet.

VAR SAVE pio1%() in assembler program and another program just needs to DIM an array of the same name for it to VAR RESTORE.  I haven't looked at multiple variables being VAR SAVEd, but there shouldn't be a problem.
led
Miss you George
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 5740
Posted: 08:02am 20 Aug 2021
Copy link to clipboard 
Print this post

The RPi docs ignore the Pico pin numbers and use the signal name or GPIO number, as per the numbering on the RP2040 itself. That makes sense. It's a good idea, IMHO, to stick with it (just substituting GPn for GPIOn) when programming the PIO as it is universal across all RP2040 boards. The PicoMite pin numbers will only work with that one board and maybe one or two more that have used the same connections. There's no reason to think that GPIO0, for example, will always be on pin 1. If you just purchase the chip and use it on your own board then GPn based programs will port directly, board pin number based programs won't.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 5740
Posted: 05:18pm 20 Aug 2021
Copy link to clipboard 
Print this post

Have a new toy to play with...
PREVAS 011.zip
This is a reverse-assembler (disassembler) that reads a *.PIO file and converts it back into opcodes. It's a bit crude, but seems to work.

*.PIO files can be written by the fileman routine in PASM. They contain the program array and all the state machine register arrays.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 10:32pm 24 Aug 2021
Copy link to clipboard 
Print this post

Here is some code to generate 50/60Hz O/P on three pins of the pico using PIO.
Some filtering may just get you some reasonable 3 phase sinusoidal O/Ps.
It is not perfect due to differing delays in the assembler code which can be fixed with some effort.
Note: there is a minimum frequency set in the call to PIO INIT MACHINE function. I settled on 5kHz (& 6kHz) for the smallest amount of delay cycles.

PIO Assembler:
Data "set pindirs 7"     ' Bitmap of first 3 pins GP0-2
Data "set pins 5 [16]"   ' Pins GP0 & GP2 (physical pins 1 & 4)
Data "set pins 1 [15]"   ' Pin  GP0
Data "set pins 3 [16]"   ' Pins GP0 & GP1
Data "set pins 2 [15]"   ' Pin  GP1
Data "set pins 6 [16]"   ' Pins GP1 & GP2
Data "set pins 4 [15]"   ' Pin  GP2
Data "jmp 1"
Data ""

' Data contained in asmblock()
' and VAR SAVEd by the assembler program
&HF003EF01F005E087
&H0001EF04F006EF02
6 @ &HA042A042A042A042 nops
----------------------------
' PIO program that can output 50/60Hz squarewave on GP0-2 (3 pins > 3 phases)
Option Explicit

DIM integer asmblock(7)

VAR RESTORE         ' Retrieve PIO code into asmblock()

' Preparations : reserve GP0-2 for PIO
SetPin 1,pio0
SetPin 2,pio0    ' Pin 3 Gnd
SetPin 4,pio0

PIO clear 0
PIO PROGRAM 0,asmblock()

' Set clock 5kHz for 50Hz on pio0 sequencer 0
' or change frequency to 6kHz for 60Hz
' Assign 3 pins to SET group and assign a base of 0.
PIO init machine 0,0,5000,pio(pinctrl 0,3,0,0,0,0)

' Start the output
PIO start 0,0

PIO execute 0,0,0
Do
  Print ".";  ' do something to show we are working...
  Pause 1000
Loop
----------------------------


Edit: This is a copy from another thread, but would like to keep any example PIO code in a central location for easier access by anyone interested in PIO programming.
Miss you George
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 02:37am 26 Aug 2021
Copy link to clipboard 
Print this post

Some mainline code to pass data through a FIFO and output onto a single pin.
There is extra comments and info/data to help me understand what's going on.
Hopefully it helps you too.  Note that  PIO(shiftctrl...) parameter needs
to be 'OR'ed with &H80000 to get the data bits moving out ok (with MSBit first).

' PIO - Send data bytes through FIFO and O/P on pin 1
Option explicit

' Tests 1-10 program data, only one array used for each test!
Dim integer test01(7),test02(7),test03(7),test04(7),test05(7)
Dim integer test06(7),test07(7),test08(7),test09(7),test10(7)
Dim integer i
Dim integer dum1, dum2, dum3   ' Testing

' Retrieve test05 program data
VAR RESTORE

'test05:
'Data "SET pindirs 1"
'Data "PULL"        ' Wait here until data in FIFO
'Data "SET y 8"     ' Counter
'Data "OUT pins 1"
'Data "JMP y-- 3"
'Data "JMP 1"
'Data ""

SetPin 1,pio0

PIO clear 0

PIO PROGRAM 0,test05()

' O/P on GP0 from FIFO I/P
dum1=Pio(pinctrl 0,0,1,0,0,0) ' ONLY 1 OUT pin in use, base 0
'dum1=&H00100000
dum2=Pio(execctrl 0,0,31)     ' [Optional] Def: wrap bottom to top
'dum2=&H0001F000
dum3=Pio(shiftctrl 1,0,0,0) Or &H080000  ' Change direction O/P
'dum3=&H10080000               ' Pull threshold 8 bits, NO auto_pull

' Set clock for pio0, machine 0, 100kHz
' Assign 1 pin to SET group, base 0 (pinctrl)
PIO INIT machine 0,0,100000,dum1,,dum3

' and start the output
PIO START 0,0

PIO EXECUTE 0,0,0 'entry point for phase 1  pin 1

Do
   PIO WRITE 0,0,2,&H99,&H99      ' output 2 bytes to the pio
   Pause 20
   i = i + 1
   If i Mod 100 = 0 Then Print ".";
Loop


led
EDIT: Took out some BS (left a lot more in!)
Edited 2021-08-26 14:43 by led-bloon
Miss you George
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3558
Posted: 06:36am 26 Aug 2021
Copy link to clipboard 
Print this post

Thank you led-bloon. I am thrived to see that you are getting to grips with the PIO sequencer. Small steps, but educating us, and learning yourself.

This last program "test05" shows where I feel the doubt whether PIO sequencer and MMBasic (as it is now) are a good pair.

I think the RP2040 dev team have set up an architecture where the fast real time IO stuff is handled by the PIO sequencer, with a ARM M0 core to supply the PIO sequencer with information (data server). The second M0 core would run the main program. That way the second M0 core could run an interpreted language (python/Basic) and not be an roadblock for the PIO sequencer and first M0 core.

As you can see in many demo's, that second M0 core is not used in python either, and PIO sequencer is depending on python to supply it with data. We are in the same boat. MMBasic interpreted language must supply the PIO sequencer with data AND run the main program.

I myself see no solution yet. Bringing up the second M0 core and setting it up as a server for PIO sequencer data is simply adding a new layer of complexity. MMBasic program, sequencer program (from PASM), sequencer configuration (INIT machines), data server program (new), data server configuration (new). Maybe the data server can be simplified to simply supply a memory block (a DMA) to each sequencer, and you configure it to supply the data to a output register and take from a input register. But I may be over simplifying the function.
Edited 2021-08-26 16:38 by Volhout
PicomiteVGA PETSCII ROBOTS
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 07:28am 26 Aug 2021
Copy link to clipboard 
Print this post

  Quote  We are in the same boat. MMBasic interpreted language must supply the PIO sequencer with data AND run the main program.


This is true but does not mean the PIO are not useful. You just need to use them in ways that make sense given the constraints

The RP2040 SIO is already very fast so any application that needs to output or input continuous streams of data has little advantage to using PIO (other than reducing but not eliminating the impact of processor interrupts). Output to a SPI display is an example where there is little advantage to using PIO.

However, if we look at asynchronous activity with limited interaction with the main processor then the PIO start to make sense.

An obvious example is reading a quadrature encoder. The PIO can do this completely by itself and the main processor can then poll when required to read the current value.

Likewise led-bloon's example of generating a 3 phase output is perfect for PIO.

I am perfectly willing to look at further enhancements of the MMBasic I/F to PIO if a "real" use case can be defined. For example single shot or continuous I/O to/from a MMBasic array using DMA, or linking a MMBasic subroutine to a PIO H/W interrupt.
However, if I am to do this I need someone to properly define the use case and undertake to develop the PIO routines.

The second strand to this is use of the second processor. This is pretty much impossible in an interpreted language. However, it could be that MMBasic could I/F with CSUBs that would run on the second processor and that could do some interesting stuff.

This stuff is all hard and I'm not going to do it on a speculative basis but as stated above would need a partner with the requisite skills (writing PIO assembler and/or C) and a real use case that might benefit the wider community.
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 09:28am 26 Aug 2021
Copy link to clipboard 
Print this post

I originally had in mind VGA 640x480 (composite?) B/W only needing 38k RAM + 3 IO pins. It would still leave approx 75k RAM for users and 26 GPIO pins. If the PIO WRITE function were to take an array of bytes, probably no need for DMA either.
All "airy fairy" stuff right now though, still having fun!
led
Edit: I take it back, DMA would still be required!
Edited 2021-08-26 19:33 by led-bloon
Miss you George
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 3558
Posted: 10:04am 26 Aug 2021
Copy link to clipboard 
Print this post

Hi Peter,

I am currently occupied with a project that uses the ADC function. Apart from the 3 phase generator (that I have running on a Arduino nano right now) I do not have a concrete PIO project ahead. But when it shows up, I will not hesitate to discuss with you when it cannot be solved with the existing functions.

I am lousy at C, actually I am not a programmer at all (it is more "try and error") but when the opportunity is there I will try.

Regards,

Volhout
PicomiteVGA PETSCII ROBOTS
 
led-bloon

Senior Member

Joined: 21/12/2014
Location: Australia
Posts: 203
Posted: 01:15am 27 Aug 2021
Copy link to clipboard 
Print this post

My previous block of code has problems and I am playing some more but...
I think VGA from the PicoMite would best come from the second core with everything at its disposal.
led
Miss you George
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 06:50am 27 Aug 2021
Copy link to clipboard 
Print this post

  Quote  I think VGA from the PicoMite would best come from the second core with everything at its disposal.
led


I've played with this - it doesn't work. Timing is affected by memory access conflicts so execution time is not guaranteed to be accurate
 
     Page 1 of 4    
Print this page
© JAQ Software 2024