Menu
JAQForum Ver 26.09

Forum Index : Microcontroller and PC projects : Picomite user manual V6.04.00 errata

Posted: 08:22pm
21 Sep 2026
Copy link to clipboard
TassyJim
Guru


Page 111 MM.Info
MM.Info(BOOT COUNT) is out of alignment with it's description.
Caused by the addition of Brownout as a reason for MM.INFO(BOOT)
It affects the rest of that page.


VK7JH
MMedit
 
Posted: 09:57pm
21 Sep 2026
Copy link to clipboard
matherp
Guru

Thanks - done and updated in the release
 
Posted: 12:50am
24 Sep 2026
Copy link to clipboard
phil99
Guru


In Apendix F PIO example programs many comments are preceded with a back quote instead of a single quote.
Below I have attempted to correct them all. If any have been missed or any other typos are found please note them here.

EXAMPLE PROGRAM 1
A complete PIO implementation that toggles a GPIO pins can be implemented in MMBasic as shown below.
Connect a buzzer to GP0, and hear the audio tone generated by the PIO.

'disconnect ARM from GP0
setpin gp0,pio1 'use GP0 as output pin for PIO 1

'pio program used
  '0 E081         'SET pin output
  '1 E001         'SET pin high
  '2 E000         'SET pin low
  '3 0001         'jmp 1

'program pio 1 using an array to write the program in PIO memory, and start
  Dim a%(7)=(&h0001E000E001E081,0,0,0,0,0,0,0)
  PIO program 1,a%()

'configure pio 1 statemachine 0
  p=Pio(pinctrl 0,1,,,,gp0,)  'define SET uses 1 pin, and that is GP0
  f=3100                      '3051 Hz is lowest frequency CPUSPEED 200000
  PIO init machine 1,0,f,p    'use default for execctrl, shiftctrl, start address(=0)

'start the PIO 1 state machine 0
  PIO start 1,0


EXAMPLE PROGRAM 2
Below program explains many of the above presented MMbasic functions and commands. The program reads a
NES controller (SPI) connected to the Raspberry Pi Pico. The NES controller consists of a HEF4021 shift
register connected to 8 push button switches.
Program uses: wrap and wrap target, IN, side set and delay, PUSH, PIO READ. GP0 and GP1 are in SET for
pin direction, and in side set for compact code.
The wiring is as defined in the code:

'disconnect ARM from GP0/1/2
  setpin gp0,pio1          'clock out
  setpin gp1,pio1          'load out
  setpin gp2,pio1          'data in

'PIO program

PIO assemble 1,".program NES"     'a program needs a name
.side set 2                       'use 2 bits for side set, 3 for delay
.line 0                           'start code at line 0
   SET pindirs,&b11               'set GP0,GP1 output, side GP0,GP1 low
.wrap target                      'wrap target = top of the loop
   IN null,32 side 2              'set ISR to 0, GP1 high (load), GP0 low
   SET X,7 side 0                 'set X counter to 7, GP0,GP1 low
.label loop: 'inner loop label
   IN pins,1 side 0               'shift 1 databit in, keep GP0,GP1 low
   JMP X-- loop side 1            'jmp to loop, dec. X, GP0 'high(clock)
   PUSH side 0 [7]                'now X=0, PUSH result into FIFO, delay 7
.wrap"                            'end outer loop, repeat
.end program list                 'end of program, list result

'configure pio1
  p=Pio(pinctrl 2,2,,gp2,gp0,gp0,) 'GP0,GP1 out (SET and SIDESET), GP2 IN
  f=1e5 '100kHz
  s=PIO(shiftctrl 0,0,0,0,0,0)     'shift in from LSB for IN (and OUT)
  e=PIO(execctrl gp0,PIO(.wrap target),PIO(.wrap)) 'wrap and wrap target

'write the configuration
  PIO init machine 1,0,f,p,e,s,0   'start at line 0

'start the pio1 code
  PIO start 1,0

'Check the read data in MMBasic and print
  dim d%
  do
    pio read 1,0,1,d%
    print bin$(d%)
    pause 200
  loop
END


Example :
DIM packed%                 'watch out: NO brackets()
PIO MAKE RING BUFFER packed%,4096

packed% will then be an integer array holding 4096/8 = 512 integers
This can then be used by the DMA for a loopback counter with DMA of 1024 32-bit words, 2048 16-bit shorts
or 4096 8-bit bytes.

EXAMPLE PROGRAM 3
This program brings everything together and uses DMA to read 128 samples from the PIO RX FIFO. For the
demonstration, GP0 to GP5 are outputs of 3 PWMS, and are, at the same time, sampled by the PIO as a 6
channel logic analyzer or oscilloscope. The 128 samples are sent to the serial port as waveforms.
This Logic Analyzer program also demonstrates PIO DMA RX, MEMORY UNPACK, the use of buffers. It
uses PWM’s to generate a test signal on gp0..gp5 for demo purpose. These same pins are read by the logic
analyzer and output to the console.
To use this Logic Analyzer normally comment out first 14 lines.

'generate a 50Hz 3 phase test signal to demonstrate the DMA on 6 GPIO pins.
SetPin gp0,pwm 'CH 0a
SetPin gp1,pwm 'CH 0b
SetPin gp2,pwm 'CH 1a
SetPin gp3,pwm 'CH 1b
SetPin gp4,pwm 'CH 2a
SetPin gp5,pwm 'CH 2b

Fpwm = 50: PW = 100 / 3
PWM 0, Fpwm, PW, PW - 100, 1, 1
PWM 1, Fpwm, PW, PW - 100, 1, 1
PWM 2, Fpwm, PW, PW - 100, 1, 1
PWM sync 0, 100/3, 200/3

'------------------------------- LA code PIO --------------------------
'PIO code to sample GP0..GP6 as elementary logic analyzer
PIO clear 1

'in this program the PIO reads GP0..GP5 brute force
'and pushes data into FIFO. The clock speed determines the
'sampling rate. There are 2 instructions per cycle
'taking 10000/2 / 50 = 100 samples per 50Hz cycle.

PIO assemble 1,".program push"
  .line 0
  .wrap target
    IN pins,6                                    'get 6 bits from GP0..GP5
    PUSH block                                   'push data when FIFO has room
  .wrap
.end program list


'Configuration
f=1e4 'PIO run at 10kHz
p=Pio(pinctrl 0,0,0,gp0,,,)                      'IN base = GP0
e=Pio(execctrl gp0,PIO(.wrap target),PIO(.wrap)) 'wrap 1 to 0, gp0 is default

s=Pio(shiftctrl 0,0,0,0,0,0)               'shift in through LSB, out is not used

'write the configuration, speed 10kHz (data in FIFO 10us after edge GP0)
PIO init machine 1,0,f,p,e,s,0                   'start address = 0

'-------------------------- LA code MMBasic ----------------------------
'define memory buffers
  Dim a$(1)=("_","-")                               'characters for the printout
  length%=64                                        'size of the packed array
  Dim data%(2*length%-1)                            'array to put the 32 bit samples

'FIFO format
  Dim packed%(length%-1)        'DMA array to pack 32 bit samples in 64 bit integers

'let the DMA machine run, and repeat at will
Do
  PIO DMA RX 1,0,2*length%,packed%(),ReadyInt
  print "press any key to restart sampling"
  do:loop while inkey$=""
Loop
End

‘--------------------------------SUBS MMBasic --------------------------
Sub ReadyInt
  'stop the PIO and re-init for next runPage 256 PicoMite User Manual
  PIO stop 1,0
  PIO init machine 1,0,f,p,e,s,0 'start address = 0

  'get the data from the packed DMA buffer and unpack to original 32 bit format
  Memory unpack packed%(),data%(),2*length%,32

  'Serial output as if logic analyzer traces
  For j=0 To 5
    mask%=2^j
    For i=0 To 2*length%-1
      If i<106 Then Print a$(((data%(i) And mask%)=mask%));
    Next i
  Print : Print
  Next j
End Sub



EXAMPLE PROGRAM 4
This program runs on RP2350 only and demonstrates the use of the FIFO’s as individual registers.
The PIO of the RP2350 has specific instructions to support this:
 MOV RXFIFO[y],ISR
and
 MOV OSR,RXFIFO[y]

MMBasic can read/write the 4 individual FIFO registers by use of:

PIO WRITEFIFO a, b, c, d
PIO READFIFO( a, b, c)
    a/ pio (0,1 or 2(2350 only))
    b/ state machine (0...3)
    c/ nbr (FIFO register 0…3)
    d/ data% (32 bit integer value)

The program configures the FIFO for individual reads, then writes some values in these register.
It starts the PIO that updates 2 of the 4 individual FIFO registers. Then MMBasic reads the values
to show only 2 registers have changes, and no data shifted (as would happen in RP2040 FIFO).

'only for RP2350 assembler. this does not work on RP2040

pio clear 1

pio assemble 1,".program test"
.line 0
set y,4                                       'just a value 4 in Y
mov isr,y                                     'copy Y to isr
jmp y--,next                                  'y=y-1 always to next
.label next                                   'label
  mov rxfifo[y],isr                           'should program 4 in fifo [3]
  mov isr,y                                   'copy Y to isr
  mov rxfifo[2],isr                           'should program 3 in fifo [2]
jmp 0 'repeat
.end program

f=1e6 '1MHz

'PIO(EXECCTRL a,b,c)
e=pio(execctrl gp0,0,31)                      'default value, not actually changed

'PIO(SHIFTCTRL a,b,c,d,e,f,g,h,i,j)
sr=pio(shiftctrl 0,0,0,0,0,0,0,0,0,1)         'read individual RX, RX=4 deep
sw=pio(shiftctrl 0,0,0,0,0,0,0,0,1,0)         'write individual RX, RX=4 deep

'PIO(PINCTRL a,b,c,d,e,f,g)
p=pio(pinctrl 0,0,0,gp0,gp0,gp0,gp0)          'defaultvalue , not actually changed

'test the use of FIFO as individual registers
'fill the fifo with pre-determined values
pio init machine 1,0,f,p,e,sw,0               'init machine for writing to RX fifo
for i=0 to &h3                                'write the 4 RXFIFO registers
  pio writefifo 1,0,i,&h100*(i+1)             'write values &h100, &h200, &h300, &h400
next

'check the values are written correctly
print "3 RXFIFO registers before running the program"
pio init machine 1,0,f,p,e,sr,0               'init machine for reading the RX fifo
for i=0 to 3                                  'read the 4 RXFIFO registers
  print i,hex$(pio(readfifo 1,0,i))           'verify they are correctly written
next
print

'run the PIO program. That should (continuously) write to reg 2 and 3 in the FIFO,
'but not alter register 0 and 1
pio start 1,0

'show the updated FIFO registers
print "3 RXFIFO registers after running the program"
for i=0 to 3                    'read the 4 FIFO registers to see if the program works
  print i,hex$(pio(readfifo 1,0,i))
next


The expected output is:
3 RXFIFO registers before running the program
0        100
1        200
2        300
3        400

3 RXFIFO registers after running the program
0        100
1        200
2        3
3        4


EXAMPLE PROGRAM 5
Finally an example program showing how multiple state machines can work together, each one triggered
from an interrupt from the other one. Note also the use of .LINE NEXT as starting point of the second
program, and the use of x=PIO(NEXT LINE) to determine the starting point of the second program.

IRQ 1 sets and IRQ. When the other state machine is waiting WAIT 1 IRQ 1, it continues after IRQ 1
found set, and clears the IRQ 1 at same time.

‘test for PIO IRQ's on PIO 0 state machines 0 and 1

'uses GP0 and GP1
  setpin gp0,pio0
  setpin gp1,pio0
  pio clear 0

'target frequency for PIO
  f=1e5 '100kHz

pio assemble 0
  .program sm0
  .line 0
    set pindirs,1                   'set GP0 out, see pinctrl
  .wrap target
    set pins,1 [31]                 'set GP0 high, wait 31 cycles
    set pins,0 [31]                 'set GP0 low, wait 31 cycles
    irq 0                           'set IRQ 0
    wait 1 irq 1                    'wait until sm1 sets IRQ 1
  .wrap
.end program list

  ln=pio(next line)                 'remember the line in the program
  p0=pio(pinctrl 0,1,,,,gp0)        'GP0 is pin for SET
  e0=pio(execctrl gp0,pio(.wrap target),pio(.wrap))

pio assemble 0
  .program sm1
  .line next
    set pindirs,1                   'set GP1 output
  .wrap target
    wait 1 irq 0                    'wait for IRQ 0
    set pins,1 [31]                 'set GP1 high and wait 31 cycles
    set pins,0 [31]                 'set GP1 low and wait 31 cycles
    irq 1                           'set IRQ 1
  .wrap
.end program list

  p1=pio(pinctrl 0,1,,,,gp1)
  e1=pio(execctrl gp0,pio(.wrap target),pio(.wrap))

  pio init machine 0,1,f,p1,e1,,ln  'start sm1 at line ln
  pio init machine 0,0,f,p0,e0,,0   'start sm0 at line 0

  pio start 0,1
  pio start 0,0

do:loop                             'do nothing, let PIO generate the signals
end

Edited 2026-09-24 11:03 by phil99
 
Posted: 02:33am
24 Sep 2026
Copy link to clipboard
Peter63
Senior Member

uuppsss  missed some changes...

program 3
‘--------------------------------SUBS MMBasic --------------------------

program 5
‘test for PIO IRQ's on PIO 0 state machines 0 and 1

/Peter63
 
Posted: 07:36am
24 Sep 2026
Copy link to clipboard
matherp
Guru

Manual updated with the fixes in the RC1 release
 
Posted: 07:40am
24 Sep 2026
Copy link to clipboard
phil99
Guru


Thanks Peter and Peter.
 
Posted: 08:39am
24 Sep 2026
Copy link to clipboard
phil99
Guru


It would appear I had some of the line lengths wrong for the PDF formatting.
Some adjustments needed.

EXAMPLE PROGRAM 3
'-------------------------- LA code MMBasic ----------------------------
'define memory buffers
Dim a$(1)=("_","-") 'characters for the printout
length%=64 'size of the packed array
Dim data%(2*length%-1)                     'array to put the 32 bit samples
                                          'FIFO format  <---I think "in" needs to be inserted after the quote
Dim packed%(length%-1)             'DMA array to pack 32 bit samples 'in 64
                                   bit integers
 <---quote needs to be moved to this line
.
.
.
'--------------------------------SUBS MMBasic --------------------------
Sub ReadyInt
'stop the PIO and re-init for next run

                                                   Page 255 PicoMite User Manual

PIO stop 1,0
PIO init machine 1,0,f,p,e,s,0 'start address = 0
'get the data from the packed DMA buffer and unpack to original 32 bit 'format  <---unneeded quote
Memory unpack packed%(),data%(),2*length%,32


EXAMPLE PROGRAM 4
print
'run the PIO program. That should (continuously) write to reg 2 and 3 in the FIFO,
but not alter register 0 and 1 <---missing quote
pio start 1,0

Edited 2026-09-24 19:04 by phil99
 
Posted: 05:41am
02 Oct 2026
Copy link to clipboard
phil99
Guru


Perhaps an addition to the end of Special Device Support - IR Remote Control

"Subroutines for other IR Remote Control Rx and Tx protocols can be found on Fruit of the Shed.
https://fruitoftheshed.com/wiki/doku.php?id=mmbasic:start"
 


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026