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 : PicoMite sine waves?
Page 3 of 5 | |||||
Author | Message | ||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Opens a whole new world.. A simple AWG (Arbitrary Waveform Generator) programmable in MMBasic. Such as: AM modulation Ho-ho, before the HAM readers get too excited. The picomite memory, even when optimally used can only calculate a modulation frequency of 1kHz (not lower) on a 1MHz carrier. There simply is not enough memory for lower modulation frequency. So it is nice, and you can do nifty things, but it is not capable of a 2 transistor 9 capacitor 6 resistors 1 inductor AM modulator circuit. Volhout PicomiteVGA PETSCII ROBOTS |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6798 |
Yeah - but the analogue circuit can't run Snake on a LCD display. :) That's pretty impressive anyway! Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi mIck, Don't follow this path (the ladder DAC driven from PIO with DMA) any further. There is a snag in the DMA where it stops after 2^32 FIFO transfers. Peter cannot avoid that. To achieve good sine waves you may need to run the PIO at 100MHz or more, and even if you limit to 8bit transfers (4 per FIFO word) you pull 25e6 FIFO words per second. This means your sine wave will stop after 2^32/25e6 = 171 seconds (3 minutes). I can of coarse restart the DMA, but there will be a gap/discontinuity in output signal. This is not usable for a test instrument. Volhout P.S. there is a similar problem in the logic analyzer, but that is only a small moment where the analyzer is "blind" before DMA is restarted, and there is only a small chance this actually is in your 4096 samples buffer. The trigger engine remains running, so worst that can happen is that your trigger does not show up in the buffer.... try again. Edited 2023-06-27 20:29 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Awaiting further work Edited 2023-06-27 20:42 by matherp |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3804 |
Would using a 2nd DMA channel (aka a DMA chain) fix it? But would there be a small glitch? Along the lines of this John Edited 2023-06-27 20:57 by JohnS |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6798 |
It looks like the DMA ping-pong system has been made to work (in Python anyway). Whether anyone has run it for long periods I don't know. :) https://www.instructables.com/Arbitrary-Wave-Generator-With-the-Raspberry-Pi-Pic/ A circular buffer with a single DMA channel has its appeal as a more elegant solution though. Would anything be gained by using the double-length input buffer on the PIO? Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Since the DMA feeds FIFO, and FIFO contains at lease 3 samples, there may be an opportunity DMA restarts itself. There may be sufficient time. In that case we only need to align the "nbr" value as a multiple of the "loopback" value. Peters message might indicate he is looking into it himself. In that case I have full confidence it will be solved. This is not the first time he did made impossible possible. Volhout. PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Volhout Are you testing on PicoMite or PicoMiteVGA? Let me know and I'll post a test version with continuous DMA |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi Peter, My test runs on a standard picomite. Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Try this Set the number to 0 (from &HFFFFFFFF) and remove the completion interrupt PicoMite (3).zip Tested on the VGA version but this should be the same |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi Peter, The DMA runs continuous, that is super !. But it cannot be stopped anymore (PIO DMA TX OFF). The running status is visible MM.INFO(PIO TX DMA), so that is okay. Just stopping it won't work, it remains running. When you restrts the DMA anyway you get an error message, and the Pico locks up. Normally you would stop the DMA to change the PIO frequency, or the pkd%() array content. Good work, almost there... Volhout P.S. could you elaborate a bit on the constraints ? IS this fix for RX and TX DMA's,or only for TX. Does it combine 2 DMA's in one action ? (if you use TX then there is not RX anymore) ? Does the ARM restart the DMA ? or is it restarting itself ? Would the MMBasic interface be simpler when the DMA loopback was a flag (boolean), and "nbr" the ring buffer size ? Edited 2023-06-28 22:08 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Another try PicoMite (4).zip Should work for RX but doesn't seem to but logic analyser is a bit too complex to use as a test. If you can provide a much simpler test program that would be helpful Simultaneous TX and RX still both available - used 2 more dma channels as the control channels Not intending to change the I/F as fixed in the manual. Just an extra phrease needed for the new functionality Edited 2023-06-29 00:01 by matherp |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi Peter, This works for TX !! I will see if I can make a simple test for the RX tonight. Thank you Volhout PicomiteVGA PETSCII ROBOTS |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
@Peter, RX_DMA also works with ring buffer 'demo for RING buffer DMA SetPin gp9,pio1 'program PIO, pushes data every 2 cycles into the FIFO PIO assemble 1,".program NES" PIO assemble 1,".line 0" PIO assemble 1,".wrap target" PIO assemble 1,"IN pins,1" PIO assemble 1,"PUSH block" PIO assemble 1,".wrap" PIO assemble 1,".end program"' list" 'a program needs a name 'config PIO p=Pio(pinctrl 0,0,0,gp9,,,) 'gp9 is base IN s=Pio(shiftctrl 0,0,0,0,1,0) 'shift in through LSB e=Pio(execctrl gp0,Pio(.wrap target),Pio(.wrap)) f=133e6 'high speed to achieve DMA end as fast as possible (picomite 1330MHz CPU) PIO init machine 1,0,f,p,e,s,0 'ring buffer creation Dim ring% 'this will become the ring buffer PIO make ring buffer ring%,4*1024 '4096 bytes Print "time DMA running" 'start DMA (DMA starts PIO program PIO DMA RX 1,0,&H7FFFFFFF,RING%(),ReadyInt,32,1024 '5.0707 'PIO DMA RX 1,0,0,RING%(),,32,1024 '5.0708rc6 'CHECK if DMA still running Timer =0 Do Pause 1000 Print Int(Timer/1000),MM.Info(pio RX dma) Loop End Sub ReadyInt Print "DMA stopped" PIO stop 1,0 End Sub With the 5.0707 code use the PIO DMA RX 1,0,&H7FFFFFFF,RING%(),ReadyInt,32,1024 The listing stops after 32 seconds. time DMA running 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 1 20 1 21 1 22 1 23 1 24 1 25 1 26 1 27 1 28 1 29 1 30 1 31 1 32 1 DMA stopped 33 0 34 0 35 0 36 0 With the 5.0708rc6 code use the PIO DMA RX 1,0,0,RING%(),,32,1024 The listing goes on, and on ... tested several minutes. Don't list here.... too long. Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Is it reading properly if you look at the array? |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Easiest to try in the logic analyzer, is it much work to create a VGA version? Volhout Edited 2023-06-29 05:17 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Can we focus on this one as it is simple. As I understand it I should be able to print ring%(0) in the timer loop and it should show the state of GP9. This doesn't seem to work even for the version that loops the finite number of times. If we can get that to work I can then diagnose the continuous version |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi Peter, There is something in the way the infinite ring buffer is implemented. Below program is a small adaption of the example program in the user manual. You start it, and when you press space bar (any key) you see on the serial port a 6 channel logic analyzer signal. It uses GP0..6. This is based on ring buffer using a large "nbr" value. You can wait several seconds and each time you press a key you see logic analyzer signals. Sometimes you see clearly when the ring buffer overlaps previous cycle (disruptions on all 6 channels at same time) comment line 48, and un-comment line 49 (nbr=0) and the command locks up. Something is not okay when nbr=0 '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 analyser 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" PIO assemble 1,".line 0" PIO assemble 1,".wrap target" PIO assemble 1,"IN pins,6" 'get 6 bits from GPIO pins (GP0..GP5) PIO assemble 1,"PUSH block" 'only push data when FIFO has room PIO assemble 1,".wrap" PIO assemble 1,".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 not used s=Pio(shiftctrl 0,0,0,0,0,0) 'shift in through LSB, out is not used 'write the configuration, running 10kHz (data in FIFO 10us after rising 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 dim pkd% PIO MAKE RING BUFFER pkd%,length%*8 'let the DMA machine run, and repeat at will Do PIO DMA RX 1,0,4000*length%,pkd%(),ReadyInt,32,2*length% 'PIO DMA RX 1,0,0,pkd%(),,32,2*length% print "press any key to print buffer and restart sampling" do:loop while inkey$="" PIO stop 1,0 PIO init machine 1,0,f,p,e,s,0 'start address = 0 if mm.info(pio rx dma) then pio dma rx off Memory unpack pkd%(),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 Loop End '-----------------------------------SUBS MMBasic -------------------------------- Sub ReadyInt 'stop the PIO and re-init for next run PIO stop 1,0 PIO init machine 1,0,f,p,e,s,0 'start address = 0 End Sub Edited 2023-06-30 01:30 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi Peter, I have modified the PIO program somewhat to give more detail. GP4 goes high when the BLOCKING PUSH into FIFO happens and goes low after the PUSH was succesfull. So when DMA does not empty the FIFO, GP4 is fixed high, the PIO program is stalled. While DMA is running GP4 is pulsing (2.5kHz). A scope gives insight. You start the DMA with nbr=0 and the FIFO is read by the DMA (2.5kHz pulses). When you hit the keyboard, it should stop PIO,DMA, and read ring buffer. But that goes wrong. The PIO program is stopped (randomly, sometimes GP4 high, sometimes GP4 low), but the PICO does not answer anymore to keyboard (USB) and needs reset. I guess stopping the DMA causes this. The text "RX DMA is OFF" never appears on the terminal. See below log Saved 2891 bytes 0: E081 1: E000 2: 4006 3: E001 4: 8020 press any key to print buffer and restart sampling PIO stopped PIO re-init The program used is this: 'generate a 50Hz 2 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 Fpwm = 50: PW = 100 / 3 PWM 0, Fpwm, PW, PW - 100, 1, 1 PWM 1, Fpwm, PW, PW - 100, 1, 1 PWM sync 0, 100/3 '----------------------------------- LA code PIO -------------------------- 'PIO code to sample GP0..GP4 as elementary logic analyser PIO clear 1 'pin GP4,GP5 for diagnostics SetPin gp4,pio1 SetPin gp5,pio1 'in this program the PIO reads GP0..GP5 brute force 'and pushes data into FIFO. The clock speed determines the 'sampling rate. There are 4 instructions per cycle 'taking 10000/4 / 50 = 50 samples per 50Hz cycle. PIO assemble 1,".program push" PIO assemble 1,".line 0" PIO assemble 1,"set pindirs,1" 'set gp4 output PIO assemble 1,".wrap target" PIO assemble 1,"set pins,0" 'set gp4 low PIO assemble 1,"IN pins,6" 'get 6 bits from GPIO pins (GP0..GP5) PIO assemble 1,"set pins,1" 'set gp4 high when waiting for push PIO assemble 1,"push block" 'only push data when FIFO has room PIO assemble 1,".wrap" PIO assemble 1,".end program list" 'configuration f=1e4 'PIO run at 10kHz p=Pio(pinctrl 0,1,0,gp0,,gp4,) 'IN base = GP0, set base GP4 e=Pio(execctrl gp0,Pio(.wrap target),Pio(.wrap)) 'wrap 1 to 0, gp0 is default not used s=Pio(shiftctrl 0,0,0,0,0,0) 'shift in through LSB, out is not us ed 'write the configuration, running 10kHz (data in FIFO 10us after rising edge G P0) 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 Dim pkd% PIO MAKE RING BUFFER pkd%,length%*8 'let the DMA machine run, and repeat at will Do 'PIO DMA RX 1,0,4000*length%,pkd%(),ReadyInt,32,2*length% PIO DMA RX 1,0,0,pkd%(),,32,2*length% Print "press any key to print buffer and restart sampling" Do :Loop While Inkey$="" PIO stop 1,0 Print "PIO stopped" PIO init machine 1,0,f,p,e,s,0 'start address = 0 Print "PIO re-init" If MM.Info(pio rx dma) Then PIO dma rx off Print "RX DMA is OFF" Memory unpack pkd%(),data%(),2*length%,32 Print "ring buffer read" 'Serial output as if logic analyzer traces For j=0 To 3 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 Loop End '-----------------------------------SUBS MMBasic ----------------------------- --- Sub ReadyInt 'stop the PIO and re-init for next run PIO stop 1,0 PIO init machine 1,0,f,p,e,s,0 'start address = 0 End Sub Edited 2023-06-30 18:14 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9129 |
Thanks - that's just what I need to try and diagnose. I'll have another go at solving it now. |
||||
Page 3 of 5 |
Print this page |