Quadrature multichannel decoder for PicoMite using PIO


Author Message
allie
Regular Member

Joined: 06/10/2018
Location: Canada
Posts: 88
Posted: 10:57pm 21 May 2025      

PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1183
Posted: 04:13am 19 Aug 2024
Copy link to clipboard
Print this post
Quote

This code will handle 4 encoders on the RP2040 Picomite


 Quote  
'Quadrature multichannel decoder for PicoMite using PIO

'this is a 4 channel quadrature decoder for MMBasic V5.08.00 or newer
'running on a PicoMite or PicoMiteVGA usinf PIO 1

'Original PIO source: https://github.com/p-o-l-e/quadrature-decoder

'30-4-2024  Volhout



'system initialisation ---------------------------------------------------------

'program PIO 1
program_PIO 'program the code in PIO 1

'quadrature decoders generic settings
PIO_f%=63e6                            'frequency = 63MHz
PIO_s%=0                               'shift register (shift in left)
PIO_e%=PIO(execctrl gp0,wrp_tgt,wrap)  'start and stop of the loop

'start quadrature decoders (uncomment the needed decoders)
start_sm0 : sm0=1       'start decoder on GP0 and GP1
'start_sm1 : sm1=1       'start decoder on GP2 and GP3
'start_sm2 : sm2=1       'start decoder on GP4 and GP5
'start_sm3 : sm3=1       'start decoder on GP26 and GP27



'main MMBasic code -------------------------------------------------------------

'this code is just a demo that shows the position of the quadrature decoders
'the selected decoder positions are printed on the console
'type "r" to reset the decoders to 0

'main loop
do
 a$=inkey$                                     'just for control

 'get the data from the fifo and print
 if sm0 then print str$(read_fifo(0),12,0);    'get data from decoder
 if sm1 then print str$(read_fifo(1),12,0);    'get data from decoder
 if sm2 then print str$(read_fifo(2),12,0);    'get data from decoder
 if sm3 then print str$(read_fifo(3),12,0);    'get data from decoder
 print

 'just some pause
 pause 100                                     'any delay needed

 'reset position (PIO X register) under control of keyboard
 if a$="r" then                                'press r to zero position
   if sm0 then pio execute 1,0,&hA023 '= assembly "mov X, null" (zero X reg)
   if sm1 then pio execute 1,1,&hA023 '= assembly "mov X, null" (zero X reg)
   if sm2 then pio execute 1,2,&hA023 '= assembly "mov X, null" (zero X reg)
   if sm3 then pio execute 1,3,&hA023 '= assembly "mov X, null" (zero X reg)
   a$=""
 end if

loop while a$=""  'exit when any key not r

end




' subroutines -------------------------------------------------------------------


'this function returns the actual count of decoder n
function read_fifo(n) as integer

local dat%(3)
pio read 1,n,4,dat%()                                   'read whole fifo
read_fifo = dat%(3)                                    'last data in fifo
if read_fifo>2147483647 then inc read_fifo,-4294967296 '2'th complement

end function


'this subroutine programs the quadrature decoder program for PIO1 into
'PIO program memory
sub program_PIO

'this is the PIO program in machine code
dim p%(7)=(&h001A00170015001A,&h0015001A001A0017,&h0017001A001A0015, &h001A00150017001A,&h4042A0404042A0C3,&hA029001A005AA0A6,&h8000A0C1A0290059,0)

'here the program is programmed in memory
pio program 1,p%()

wrap=27           'end of the program
wrp_tgt=16        'start of the program loop

end sub


'this subroutine starts state machine 0 quadrature decoder on gp0 and gp1
sub start_sm0

'uses GP0,GP1, assign pins in MMBasic
setpin gp0,pio1
setpin gp1,pio1

'assign pins in PIO
pin_sm0%=PIO(pinctrl 0,0,0,gp0)

'configure and start PIO
pio init machine 1,0,PIO_f%,pin_sm0%,PIO_e%,PIO_s%,wrp_tgt
pio start 1,0

end sub


'this subroutine starts state machine 1 quadrature decoder on gp2 and gp3
sub start_sm1

'uses GP2,GP3, assign pins in MMBasic
setpin gp2,pio1
setpin gp3,pio1

'assign pins in PIO
pin_sm1%=PIO(pinctrl 0,0,0,gp2)

'configure and start PIO
pio init machine 1,1,PIO_f%,pin_sm1%,PIO_e%,PIO_s%,wrp_tgt
pio start 1,1

end sub


'this subroutine starts state machine 2 quadrature decoder on gp4 and gp5
sub start_sm2

'uses GP4,GP5, assign pins in MMBasic
setpin gp4,pio1
setpin gp5,pio1

'assign pins in PIO
pin_sm2%=PIO(pinctrl 0,0,0,gp4)

'configure and start PIO
pio init machine 1,2,PIO_f%,pin_sm2%,PIO_e%,PIO_s%,wrp_tgt
pio start 1,2

end sub


'this subroutine starts state machine 3 quadrature decoder on gp26 and gp27
sub start_sm3

'uses GP26,GP27, assign pins in MMBasic
setpin gp26,pio1
setpin gp27,pio1

'assign pins in PIO
pin_sm3%=PIO(pinctrl 0,0,0,gp26)

'configure and start PIO
pio init machine 1,3,PIO_f%,pin_sm3%,PIO_e%,PIO_s%,wrp_tgt
pio start 1,3

end sub


When I tried to get this working I got Errors stopping it. I'll try it again to find the Errors

Regards Allie