| Menu | JAQForum Ver 26.09 |
Forum Index : Microcontroller and PC projects : Picomite user manual V6.04.00 errata
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 |
||||||
Thanks - done and updated in the release |
||||||
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 '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 |
||||||
uuppsss missed some changes... program 3 ‘--------------------------------SUBS MMBasic -------------------------- program 5 ‘test for PIO IRQ's on PIO 0 state machines 0 and 1 /Peter63 |
||||||
Manual updated with the fixes in the RC1 release |
||||||
Thanks Peter and Peter. |
||||||
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 |
||||||
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" |
||||||
| The Back Shed's forum code is written, and hosted, in Australia. |