Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 14:38 28 Nov 2024 Privacy Policy
Jump to

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: Netherlands
Posts: 4247
Posted: 08:35am 27 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 6798
Posted: 09:23am 27 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 09:58am 27 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9129
Posted: 10:36am 27 Jun 2023
Copy link to clipboard 
Print this post

Awaiting further work
Edited 2023-06-27 20:42 by matherp
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3804
Posted: 10:50am 27 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 6798
Posted: 11:39am 27 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 11:49am 27 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9129
Posted: 09:08am 28 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 10:36am 28 Jun 2023
Copy link to clipboard 
Print this post

Hi Peter,

My test runs on a standard picomite.

Volhout
PicomiteVGA PETSCII ROBOTS
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9129
Posted: 10:59am 28 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 11:33am 28 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9129
Posted: 01:58pm 28 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 02:46pm 28 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 06:39pm 28 Jun 2023
Copy link to clipboard 
Print this post

@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 Kingdom
Posts: 9129
Posted: 07:02pm 28 Jun 2023
Copy link to clipboard 
Print this post

Is it reading properly if you look at the array?
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4247
Posted: 07:14pm 28 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9129
Posted: 08:08am 29 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 03:25pm 29 Jun 2023
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4247
Posted: 08:08am 30 Jun 2023
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 9129
Posted: 08:31am 30 Jun 2023
Copy link to clipboard 
Print this post

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
© JAQ Software 2024