Volhout Guru
 Joined: 05/03/2018 Location: NetherlandsPosts: 2745 |
Posted: 07:15pm 13 Dec 2022 |
|
|
|
chapter 2
- explaining the exercise with pin configurations
Last chapters exercise was about moving the 666Hz tone from pin GP0 to GP2. You did not need to change the actual program, but only the configuration.
The starting point was the GP0 configuration, that links GP0 to bit 0 of the SET command.

You can assign more pins to the SET command by increasing the number of successive pins

Or different pins, by selecting a different starting point

Knowing this the simplest answer is to assign 1 pin, named GP2. And of coarse, you need to assign GP2 to the PIO1 in a SETPIN in MMBasic.
- explaining PIO INIT MACHINE
The MMBasic command PIO INIT MACHINE writes the combined configuration values to the state machine. We have used the state machine frequency, and the state machine IO pin assignment (PINCTRL). But there are more configurations, that will be explained on further chapters.
PIO INIT MACHINE a,b,c,d,e,f,g
a/ the PIO (in our case PIO 1) b/ the state machine (0,1,2,3), we have used 0 in previosu exercise) c/ the state machine clock frequency (2000Hz in our previous exercise) d/ the pin control value (used in previous exersice to assigne GP0 to SET) e/ the execute control register (explanation will start in chapter 3 and 8) f/ the shift control register (will be explained in chapter 9 and 10) g/ the starting address of the program for this state machine (was 0 in our previous exercise)
As you may have understood from the name PIO INIT MACHINE, each state machine needs it's won init. And has it's own PINCTRL and frequency. So one state machine can run at 2kHz, the other at 63MHz, both in the same PIO. And they can actually run the same code, just at different speed. But they can also run different code, depending the start address of the state machine.
- explaining PIO STOP
As you may have noticed when running the program in last chapter, the program ends, returns the comaand promt, but the audio tone from the PIO continued. That is the indication that the PIO operates independent of the ARM, and you need to force it to stop. note: Peter (MMBasic) stops the PIO when you edit the program or restart the program.
The way to do that is PIO STOP a,b
a/ the PIO b/ the state machine.
- new: execution speed and 666Hz
The state machine executes one program line in one clock cycle. The state machine in previous chapter was running at 2kHz (0.5ms). So if we analyze the program:
LINE CODE COMMENT 0 &hE081 SET PIN OUT 0.5ms 1 &hE001 SET PIN 1 0.5ms 2 &hE000 SET PIN 0 0.5ms 3 &h0001 JMP 1 0.5ms After the SET PIN OUTPUT, the program runs a loop through adresses 1,2,3 then back to 1. A cytcle of 3 steps of 0.5ms. This makes the period of the output signal 1.5ms or 666Hz. But when we investigate what the GP0 pin is doing: LINE CODE COMMENT 0 &hE081 SET PIN OUT 0.5ms 1 &hE001 SET PIN 1 0.5ms high 2 &hE000 SET PIN 0 0.5ms low 3 &h0001 JMP 1 0.5ms no change -> low It is high 1/3 of the time, and low 2/3 of the time. That is not a nice square wave. For a nice 50% duty cycle we have the option to stretch the high level to 2 cycles. There are several options
- new: DELAY field 1/ Add a dummy instruction (reapeat the same instruction, or add a NOP 0 &hE081 SET PIN OUT 0.5ms 1 &hE001 SET PIN 1 0.5ms high 2 &hE001 SET PIN 1 0.5ms high, a dummy instruction 3 &hE000 SET PIN 0 0.5ms low 4 &h0001 JMP 1 0.5ms no change -> low
2/ Add a delay of 1 clock cycle to the SET PIN 1 instruction. This is where the DELAY field of the SET instruction plays a role.

The delay field allows up to 31 (5 bits) clock cycles delay after the instruction is executed.
If we want 1 extra clock cycle delay in the SET PIN 1 then this becomes
1 &hE101 SET PIN 1, dly=1 1ms high
And out program looks like this: LINE CODE COMMENT 0 &hE081 SET PIN OUT 0.5ms 1 &hE101 SET PIN 1 dly=1 1 ms high 2 &hE000 SET PIN 0 0.5ms low 3 &h0001 JMP 1 0.5ms no change -> low Now we have a loop of 3 instructions, but 1 instruction lasts 2 cycles, so the loop is 2ms (500Hz). The frequency can be measured using the MMBasic frequency measurement function, as suggested by phil99. I used GP8 to do that since it matches my breadboard better.
'disconnect ARM from GP0 setpin gp0,pio1
'configure pio1 p=Pio(pinctrl 0,1,,,,gp0,) f=2000 'Hz
'pio program 'line code comment ' 0 E081 GP0 output ' 1 E101 pin high, dly=1 ' 2 E000 pin low ' 3 0001 jmp 1
'program pio1 pio program line 1,0,&hE081 pio program line 1,1,&hE101 pio program line 1,2,&hE000 pio program line 1,3,&h0001
'write the configuration PIO init machine 1,0,f,p,,,0
'start the pio1 code PIO start 1,0
'Check the frequency in MMBasic Setpin GP8,FIN
pause 1000
print pin(gp8);" Hz"
PIO STOP 1,0
END
- new: ARM spying on PIO output
Peter has provided the possibility to let the ARM spy on PIO outputs. Normally you would get an erro message in case you try to read a pin that is assigned different, but for PIO he made an exemption. Since MMbasic is quite fast you can read the pin in a loop, and see the levels the PIO is putting out. From the output you can see that the duty cycle is 50% (as many 1's as there are 0's).
'disconnect ARM from GP0 setpin gp0,pio1
'configure pio1 p=Pio(pinctrl 0,1,,,,gp0,) f=2000 'Hz
'pio program 'line code comment ' 0 E081 GP0 output ' 1 E101 pin high, dly=1 ' 2 E000 pin low ' 3 0001 jmp 1
'program pio1 pio program line 1,0,&hE081 pio program line 1,1,&hE101 pio program line 1,2,&hE000 pio program line 1,3,&h0001
'write the configuration PIO init machine 1,0,f,p,,,0
'start the pio1 code PIO start 1,0
' check the GP0 pin from MMbasic
'array to store 101 samples taken from GP0 dim v%(100)
'sample the GP0 pin into the array 101 samples for i%=0 to 100 v%(i%)=pin(gp0) pause 0.1 'limit the speed a bit next i%
math v_print v%() 'print the whole array to the screen
'stop pio PIO STOP 1,0
END
RUN 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1,1 > >
- new exercise
Last time the exercise was pretty easy. This time we'll make 2 exercises, you can pick any you want, or both. They are about the current knwledge.
#1: please adapt/write a program that outputs a nice 50Hz frequency from GP0. Note that the clock frequency for the PIO cannot go below 2kHz (at 126MHz CPUSPEED.
#2: As you may have seen, Tom (thwill) bought buzzers that have a resonant frequency of 2.7kHz (they are most loud at that frequency). If this where a piezo, you need to drive it with high voltage level. This can be achieved by driving each pin of the piezo with a different IO pin. The second IO pin must be out of phase (180 degrees). This essentially is inverting the second pin.
Happy programming.....
Volhout Edited 2022-12-14 05:44 by Volhout |