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 : PIO and WebMite questions
Author | Message | ||||
homa Guru Joined: 05/11/2021 Location: GermanyPosts: 351 |
Hi guys, I'm going to try the PIOs again. First I want to receive a MIDI signal (serial 8N1 at 31250 baud). This works fine with the UARTs. But now I want to learn how to use the PIOs. I have chosen the GP15 as the input pin. I also used this source for the PIO programmer: https://github.com/raspberrypi/pico-examples/blob/master/pio/uart_rx/uart_rx.pio I have consulted the manual "Appendix F - The PIO Programming Package" and the link there. But I have problems to understand the >option list WebMite MMBasic Version 5.08.00 OPTION COLOURCODE ON Here is my Basic attempt which unfortunately fails: 'Only PIO 0 is available on the WebMite 'as PIO1 is used by the WIFI interface 'disconnect ARM from GP15 ' SETPIN GP15,PIO0 'PIO program PIO ASSEMBLE 0,".program uart_rx" 'a program needs a Name PIO ASSEMBLE 0,".wrap target" PIO ASSEMBLE 0,"start:" PIO ASSEMBLE 0,"wait 0 pin 0" PIO ASSEMBLE 0,"set x, 7 [10]" PIO ASSEMBLE 0,"bitloop:" PIO ASSEMBLE 0,"in pins, 1" PIO ASSEMBLE 0,"jmp x-- bitloop [6]" PIO ASSEMBLE 0,"jmp pin good_stop" PIO ASSEMBLE 0,"irq 4 rel" PIO ASSEMBLE 0,"wait 1 pin 0" PIO ASSEMBLE 0,"jmp start" PIO ASSEMBLE 0,"good_stop:" PIO ASSEMBLE 0,"push" PIO ASSEMBLE 0,".wrap" PIO ASSEMBLE 0,".end program list" Print "CPUspeed", MM.Info(CPUSPEED) Pause 1000 'configure pio0 p=Pio(PINCTRL 0,0,,gp15,,,) 'gp15 in f=15625 'Hz for 31250 baud, MIDI 8n1 > 31250/2 = 15625 Hz ?! s=Pio(shiftctrl 0,0,0,0,0,0) 'shift in from LSB for IN e=Pio(execctrl gp15,Pio(.wrap target),Pio(.wrap) ) 'write the configuration PIO init machine 0,0,f,p,e,s,0 'start the pio0 code PIO start 0,0 'Check the the read data in MMBasic and print Dim d%,b% Do PIO read 0,0,1,d% b%=d% Xor &hFF If b%>0 Then Print Bin$(b%), Hex$(b%) 'Pause 200 Loop End Who can help me and give me the right hint? |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 857 |
Cool 😎 We sorely need MIDI stuff |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4223 |
Hi Homa, When the uart should run 31250 baud, the PIO clock must be a multiple of that. I have no access to pico atm. Cannot help you short time. But try f=2*31250, or f=3*31250. Volhout PicomiteVGA PETSCII ROBOTS |
||||
homa Guru Joined: 05/11/2021 Location: GermanyPosts: 351 |
Hi Volhout, Thanks for your tip, according to my research it should actually be baud = Hz. But I also tried f *2 or f *3. Unfortunately without success. First I added the interrupt to separate the bytes. But the result is not what I expected :-( > run 0: 2020 1: EA27 2: 4001 3: 0642 4: 00C8 5: C014 6: 20A0 7: 0000 8: 8000 CPUspeed 133000000 11100000 E0 10000000 80 > I actually expect something like this (when I press a midi keyboad button) as it comes via UART and is correct: 10010000 90 110000 30 100000 20 110000 30 0 0 Current programme code: 'PIO program PIO ASSEMBLE 0,".program uart_rx" 'a program needs a Name PIO ASSEMBLE 0,".wrap target" PIO ASSEMBLE 0,"start:" PIO ASSEMBLE 0,"wait 0 pin 0" PIO ASSEMBLE 0,"set x, 7 [10]" PIO ASSEMBLE 0,"bitloop:" PIO ASSEMBLE 0,"in pins, 1" PIO ASSEMBLE 0,"jmp x-- bitloop [6]" PIO ASSEMBLE 0,"jmp pin good_stop" PIO ASSEMBLE 0,"irq 4 rel" PIO ASSEMBLE 0,"wait 1 pin 0" PIO ASSEMBLE 0,"jmp start" PIO ASSEMBLE 0,"good_stop:" PIO ASSEMBLE 0,"push" PIO ASSEMBLE 0,".wrap" PIO ASSEMBLE 0,".end program list" Print "CPUspeed", MM.Info(CPUSPEED) Pause 100 Dim d%,b% 'configure pio0 p=Pio(PINCTRL 0,0,,gp15,,,) 'gp15 in f=31250 '? Hz for 31250 baud, MIDI 8n1 ?!? s=Pio(shiftctrl 0,0,0,0,0,0) 'shift in from LSB for IN e=Pio(execctrl gp15,Pio(.wrap target),Pio(.wrap) ) 'write the configuration PIO init machine 0,0,f,p,e,s,0 PIO INTERRUPT 0,0,myPioRX,0 'start the pio0 code PIO start 0,0 ' MAIN Do ' PIO read 0,0,1,d% ' b%=d% Xor &hFF ' If b%>0 Then Print Bin$(b%), Hex$(b%) ' Pause 20 Loop End Sub myPioRX ' PIO stop 0,0 ' PIO init machine 0,0,f,p,e,s,0 PIO read 0,0,1,d% b%=d% Xor &hFF Print Bin$(b%), Hex$(b%) ' PIO start 0,0 End Sub Matthias Edited 2024-08-14 03:54 by homa |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9109 |
For a bitbanged serial the clock rate is typically 2x baud rate Wait for the start bit Wait 1.5x bit time repeat x8 sample input wait bit time loop If I read your code correctly you are sampling as the bit is changing |
||||
homa Guru Joined: 05/11/2021 Location: GermanyPosts: 351 |
Hello Peter, hello Volhout, I did it. Now I understand the PIO example code more and more. I still have some questions! The PIO example says the following: ; Autopush must be enabled, with a threshold of 8. // Shift to right, autopush enabled sm_config_set_in_shift(&c, true, true, 8); sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); // SM transmits 1 bit per 8 execution cycles. float div = (float)clock_get_hz(clk_sys) / (8 * baud); sm_config_set_clkdiv(&c, div); So I reduced the PIO code to the simpler example. I adjusted the frequency to the baud rate and used the MMBasic command PIO(SHIFTCTRL a,b,c,d,e,f,g,h), c/ autopush is enabled. However, a 32-bit value is returned. Is it possible to enable 8-bit autopush as in the notes? And if so, how? I have done this by adding PIO ASSEMBLE 0, "push" which solved the problem. I also had the shift direction wrong. Now: s=Pio(shiftctrl 0,0,0,0,1,0) 'shift in from MSB for IN To make the 32-Bit value correct, I added the "value>>24" to the output in MMBasic. Thanks for your suggestions! > run 0: 2020 1: EA27 2: 4001 3: 0642 4: 8000 CPUspeed 133000000 10010000 90 144 110000 30 48 1010100 54 84 110000 30 48 0 0 0 'PIO program PIO ASSEMBLE 0,".program uart_rx" PIO ASSEMBLE 0,".wrap target" PIO ASSEMBLE 0,"wait 0 pin 0" PIO ASSEMBLE 0,"set x, 7 [10]" PIO ASSEMBLE 0,"bitloop:" PIO ASSEMBLE 0,"in pins, 1" PIO ASSEMBLE 0,"jmp x-- bitloop [6]" PIO ASSEMBLE 0,"push" PIO ASSEMBLE 0,".wrap" PIO ASSEMBLE 0,".end program list" Print "CPUspeed", MM.Info(CPUSPEED) Pause 100 Dim d%,b% 'configure pio0 p=Pio(PINCTRL 0,0,,gp15,,,) 'gp15 in f=31250*8 'Hz for 31250 baud, MIDI 8n1 = *8 for the PIO-Code! s=Pio(shiftctrl 0,0,0,0,1,0) 'shift in from MSB for IN e=Pio(execctrl gp15,Pio(.wrap target),Pio(.wrap) ) 'write the configuration PIO init machine 0,0,f,p,e,s,0 PIO INTERRUPT 0,0,myPioRX,0 'start the pio0 code PIO start 0,0 'MAIN Do 'nothing Loop End Sub myPioRX PIO read 0,0,1,d% b%=d%>>24 Print Bin$(b%), Hex$(b%), b% End Sub Matthias |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4223 |
Goog work Matthias, you are understanding PIO well Thanks Peter, for helping out Volhout PicomiteVGA PETSCII ROBOTS |
||||
homa Guru Joined: 05/11/2021 Location: GermanyPosts: 351 |
Unfortunately, I haven't quite understood it yet :-( Now I want to try the other direction (send) and I fail ... It looks like the OUT does not write from the OSR to the PIN. Can anyone tell me my mistake? Matthias ' pio out TEST '-------------------------------------------------- 'Only PIO 0 is available on the WebMite 'as PIO1 is used by the WIFI interface ' 'disconnect ARM from GP14 SetPin GP14,pio0 Dim d%,b%,o% ' PIO ASSEMBLE 0,".program uart_tx" PIO ASSEMBLE 0,".side_set 1" PIO ASSEMBLE 0,"set pindirs, 1" PIO ASSEMBLE 0,".wrap target" PIO ASSEMBLE 0,"pull side 1 [7]" PIO ASSEMBLE 0,"set x, 7 side 0 [7]" PIO ASSEMBLE 0,"bitloop:" PIO ASSEMBLE 0,"out pins, 1 " PIO ASSEMBLE 0,"jmp x-- bitloop [6]" PIO ASSEMBLE 0,".wrap" PIO ASSEMBLE 0,".end program list" 'configure pio0 StateMachine 1 f=31250*8 ' a b c d e f g a,e=side set c,g=OUT p=Pio(PINCTRL 1,1,1,gp15,gp14,gp14,gp14) e=Pio(execctrl gp15,Pio(.wrap target),Pio(.wrap) ) ' 7 . s=Pio(shiftctrl 0,7,0,0,1,1) 'write the configuration PIO init machine 0,0,f,p,e,s,0 'start the pio0 code state machine 0 PIO start 0,0 'MAIN Do 'nothing Pause 500 o%=&haa Print Bin$(o%) 'Print "Status1:", Pio(FLEVEL 0 ,0 , tx) PIO write 0,0,1,o% Print "..." Loop End |
||||
homa Guru Joined: 05/11/2021 Location: GermanyPosts: 351 |
@Volhout: please check your PM, thx. Matthias |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4223 |
Hi Matthias, When using SIDE SET, a field in each instruction is reserved for SIDE SET. But there are many instructions where SIDE SET is not to be executed. There is a configuration in the EXECCTRL register that only activates SIDE SET when it is actively programmed in the assembler. In your program, change: e=Pio(execctrl gp15,Pio(.wrap target),Pio(.wrap) ) into e=Pio(execctrl gp15,Pio(.wrap target),Pio(.wrap),0,1 ) 'side set only when defined Then, it works.... So in essence, your program worked, but on each instruction (also the OUT) the hidden SIDE SET re-programmed the GPIO pin to 0. Volhout P.s. you may have to change the PULL into PULL BLOCK so you only send data when there is new data in the fifo. Edited 2024-08-24 21:10 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
homa Guru Joined: 05/11/2021 Location: GermanyPosts: 351 |
You are a genius for PIO :-) Peter was not wrong to refer to you. But why doesn't it say so in the manual or do I have tomatoes on my eyes? ... ye...no ... I found this: “[,side_pindir][,side_en]” BUT without any explanation. @geoffg: “Please add this to the manual. Especially in the appendix there is no mention of this yet!” Matthias |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4223 |
Actually, this is an omission from my side. When I wrote the text for this chapter, the 2 fields where not defined yet. At some moment in time these fields where added by Peter, and the manual was not updated. Volhout PicomiteVGA PETSCII ROBOTS |
||||
Print this page |