Shop OBEX P1 Docs P2 Docs Learn Events
Prop2 FPGA files!!! - Updated 2 June 2018 - Final Version 32i - Page 42 — Parallax Forums

Prop2 FPGA files!!! - Updated 2 June 2018 - Final Version 32i

13940424445160

Comments

  • cgracey wrote: »
    Seairth wrote: »
    ozpropdev wrote: »
    FYI All
    Just a heads up to a change to the smart pin instruction format
    In version 7z it was
    D/# = %BBBB_AAAA_FFF_PPPPPPPPPPPPP_T_D_MMMMM_1
    and in version 8 it is now
    D/# = %AAAA_BBBB_FFF_PPPPPPPPPPPPP_TT_MMMMM_0
    
    ** Note pin selection position change and bit 0 inversion **

    It might make sense to rearrange this as follows:Hu
    D/# = %PPPPPPPPPPPPP_FFF_AAAA_BBBB_TT_MMMMM_0
    

    That way, where %PPPPPPPPPPPPP_FFF is zero, PINSETM would take only 6 clocks instead of 10. In half-duplex modes, where you are frequently switching between RX and TX, this could make a difference in maximum bit rate.

    I put it the way it is so that P[7:0] is on a byte boundary, making it easy to set the DAC or comparator value. The P field is 13 bits, which is odd.

    That's solved by leaving it %FFF_PPPPPPPPPPPPP.
  • jmgjmg Posts: 15,173
    Seairth wrote: »
    * Are there any caveats if A and B point to the same pin?
    Like what ? Why would the capture logic care which pin the edges mapped to ?
    Seairth wrote: »
    * Do you have to pulse DIR to reset Z, or does it reset on PINGETZ also?
    I think some modes have loss-less reset-on-read, but this is not one of them.
    That loss-less reset-on-read is a significant difference, so needs to be made clearer.
    Seairth wrote: »
    * For the "either edge" modes, is there a way to know which edge was encountered?
    I think to get that information, you would need to use other modes, perhaps with paired pin cells ?
  • cgraceycgracey Posts: 14,155
    Rayman wrote: »
    ozpropdev's code seems to work though...

    Old (broke):
    send_char
                    pinsety tx_char,#TX_PIN  'send  character
    send_char_wait
                    pingetz temp,#TX_PIN
                    testb   temp,#31 wz,wc    
             if_nz  jmp #send_char_wait
                    ret  wz,wc
    
    Oz (works):
    send_char       pingetz temp,#tx_pin wc                   'wait if busy
            if_c    jmp     #send_char
                    pinsety tx_char,#tx_pin
                    ret wz,wc
    

    The IN signal now indicates when the transmit buffer emptied. Bit 7 from PINGETZ goes into C and it indicates "busy". Just read that mode description.
  • cgraceycgracey Posts: 14,155
    jmg wrote: »
    Seairth wrote: »
    Also, does this mean that the alternate idea of capturing sysclk instead of count was not possible?
    I'm not following this comment.
    From my reading, Time Interval A-B modes are capturing SysCLK units ?

    Or did you mean a method to capture both SysCLK and Count information, which Reciprocal Counting needs.
    I have assumed always that would need 2 pin cells, but that it would be possible.

    A quite similar situation occurs for Duty Cycle capture - you ideally want two numbers, (here they are both dT) that relate to the exact same edge(s)
    Two pin cells should be able to do this ? but can they ?

    What is missing from this mode, is a means to handle missed events.
    Users are forced to assume & hope that only one capture occurred.
    A sudden jump in calculated frequency can result, if the dT is actually more than one event.

    By sysclk, he means that the 32-bit system counter would be captured as a time marker and returned via PINGETZ.
  • jmgjmg Posts: 15,173
    edited 2016-04-13 20:52
    cgracey wrote: »
    By sysclk, he means that the 32-bit system counter would be captured as a time marker and returned via PINGETZ.
    Ah.
    The pins capture in SysCLKs now, so the only difference is phase ?.
    If the user wants Absolute Timestamps (even to 64b) , they can capture master SysCLK time, when they launch (Arm or Reset) multiple pins as Capture ?
  • jmgjmg Posts: 15,173
    cgracey wrote: »
    The IN signal now indicates when the transmit buffer emptied.
    Just curious, if you write to IN now, what happens ? Is that used for anything ?

  • RaymanRayman Posts: 14,651
    Here's my code that is supposed to monitor USB, but does nothing:
    DAT 'USB_init
                  org
                  'jmp       #@USB_init 'uncomment for hubexec  
                  'orgh $400   'uncomment for HubExec 
    USB_init
                  'Starting
                  'jmp #USB_INIT
                  
                  pinsetm pm_usb,#PinDP      'configure DP pin (passive)
                  pinsetm pm_usb,#PinDM      'configure DM pin (the brain)
                  pinsetx baud,#PinDM        'configure 12Mbps
    
                  mov     dirb,#3
                  mov     dira,##$FFFF    'enable output on p15..p0    
    
    'cog1            mov     dira,##$FFFF    'report USB status over and over
                    rep     #0,#0
                    pingetz outa,#30              
    {
    .wait           testb   inb,#1 wc      'wait for byte received (upper pin)
            if_nc   jmp     #.wait
    
                    pinack  #PinDP             'ack upper pin             
                    pingetz x,#PinDM        'get status into x
                    mov     outa,x
    
                    jmp     #.wait          'loop
    
    }
    
    DAT 'USB settings
    pm_usb          long    %1_11010_0 'low speed device
    baud            long    1228'1.5 MBPS
    
  • RaymanRayman Posts: 14,651
    edited 2016-04-13 21:11
    Oops, found problem with cut and paste from Chip's code...
    That #30 should be #32

    I'm seeing activity now, but it doesn't look right. Looks about same as before...
  • cgraceycgracey Posts: 14,155
    jmg wrote: »
    cgracey wrote: »
    The IN signal now indicates when the transmit buffer emptied.
    Just curious, if you write to IN now, what happens ? Is that used for anything ?

    Nothing, normally, but INA/INB are used to hold the debug interrupt vector and return address.
  • cgraceycgracey Posts: 14,155
    Rayman wrote: »
    Here's my code that is supposed to monitor USB, but does nothing:
    DAT 'USB_init
                  org
                  'jmp       #@USB_init 'uncomment for hubexec  
                  'orgh $400   'uncomment for HubExec 
    USB_init
                  'Starting
                  'jmp #USB_INIT
                  
                  pinsetm pm_usb,#PinDP      'configure DP pin (passive)
                  pinsetm pm_usb,#PinDM      'configure DM pin (the brain)
                  pinsetx baud,#PinDM        'configure 12Mbps
    
                  mov     dirb,#3
                  mov     dira,##$FFFF    'enable output on p15..p0    
    
    'cog1            mov     dira,##$FFFF    'report USB status over and over
                    rep     #0,#0
                    pingetz outa,#30              
    {
    .wait           testb   inb,#1 wc      'wait for byte received (upper pin)
            if_nc   jmp     #.wait
    
                    pinack  #PinDP             'ack upper pin             
                    pingetz x,#PinDM        'get status into x
                    mov     outa,x
    
                    jmp     #.wait          'loop
    
    }
    
    DAT 'USB settings
    pm_usb          long    %1_11010_0 'low speed device
    baud            long    1228'1.5 MBPS
    

    I assume PinDP=33 and PinDM=32. That should start monitoring. See if using %0_11010_0 works. It shouldn't make a difference, but in case there is a hardware bug, it might.

    Wait! The problem is that you need to change the PINGETZ to use pin 32.
  • jmgjmg Posts: 15,173
    edited 2016-04-13 21:48
    cgracey wrote: »
    The smart pin section isn't too long - at least, the first part. I recommend everyone read that, along with whatever mode they are interested in.
    Ideally, every mode should have limits and equations, which can often be clearer than words.

    Because the pin-modes are terse and lacking detail, as an exercise I started editing the simplest mode, which was called Pulse, but actually seems to be Counted Clock Output.

    eg
    X[15:0] establishes a base period in clock cycles which forms the empirical high and low times.

    :) Wow, I've no idea what a non-english designer might extract from that.

    I presumed this was trying to say
    Pin.f = SysCLK/X[15:0]
    or was it
    Pin.t = SysCLK/X[15:0]

    I think the latter has to apply, which gives an eqn of Pin.f = SysCLK/(2 * X) ; X >=1
    This means 50% duty cycles and even divisors only, and if /1 exists, it is a special case.

    Then, the next user questions will be
    Does this mode have a continual clock setting ?
    Can you start multiple pins, with a preset X phase for phased clock generation ?
    (This question also applies to NCO mode)
  • RaymanRayman Posts: 14,651
    I found the change #30 to #32 error after that post.
    Now, it works like before, not quite right...

    Also tried %0_11010_0 and didn't see a difference...
  • RaymanRayman Posts: 14,651
    P0..P15 stay at $60E5 during the entire first "IN" packet...

    Switches to $64E5 during two EOS clock cycles at end of packet then goes back to $60E5

    Later, I get $60E5 for a while then $10E5 then $9008 then $1008 and these are in 8-bit bunches...

  • Re external clock input: can this be done for streaming out too? I'm thinking it would possibly improve composite or make PAL possible with a crystal.
  • RaymanRayman Posts: 14,651
    Maybe you have to send USB before you can receive ?
  • ozpropdevozpropdev Posts: 2,792
    edited 2016-04-14 00:46
    jmg wrote: »
    cgracey wrote: »
    The smart pin section isn't too long - at least, the first part. I recommend everyone read that, along with whatever mode they are interested in.
    Ideally, every mode should have limits and equations, which can often be clearer than words.

    Because the pin-modes are terse and lacking detail, as an exercise I started editing the simplest mode, which was called Pulse, but actually seems to be Counted Clock Output.

    eg
    X[15:0] establishes a base period in clock cycles which forms the empirical high and low times.

    :) Wow, I've no idea what a non-english designer might extract from that.

    I presumed this was trying to say
    Pin.f = SysCLK/X[15:0]
    or was it
    Pin.t = SysCLK/X[15:0]

    I think the latter has to apply, which gives an eqn of Pin.f = SysCLK/(2 * X) ; X >=1
    This means 50% duty cycles and even divisors only, and if /1 exists, it is a special case.

    Then, the next user questions will be
    Does this mode have a continual clock setting ?
    Can you start multiple pins, with a preset X phase for phased clock generation ?
    (This question also applies to NCO mode)

    Here's a real world example of pulse mode based on 8)MHz sysclk
    		pinsetm	#_pulse,#pulse_pin
    		pinsetx	#80,#pulse_pin			'1uS base time
    		setb	dira,#pulse_pin
    		pinsety	#3,#pulse_pin			'start pulse 3uS length
    
    or this way for same result
    		pinsetm	#_pulse,#pulse_pin
    		pinsetx	#1,#pulse_pin			'12.5nS base time
    		setb	dira,#pulse_pin
    		pinsety	#240,#pulse_pin			'start pulse 3uS length (240 x 12.5nS = 3uS)
    
    
    same applies to transition mode,etc.

    Edit: where _pulse = %1_00100_0





  • Example of NCO mode
    		pinsetm	#_nco,#nco_pin
    		pinsetx	#1,#nco_pin
    		qfrac	##600_000,##sys_clk
    		getqx	adra
    		pinsety	adra,#nco_pin
    		setb	dira,#nco_pin	'nco freq = 600kHz
    
    and DUTY mode
    
    		pinsetm	#_duty,#duty_pin
    		pinsetx	#1,#duty_pin
    		qfrac	#80,#100
    		getqx	adra
    		pinsety	adra,#duty_pin
    		setb	dira,#duty_pin	'80% duty
    
    
  • jmgjmg Posts: 15,173
    edited 2016-04-14 01:19
    ozpropdev wrote: »
    Here's a real world example of pulse mode based on 80MHz sysclk
    		pinsetm	#_pulse,#pulse_pin
    		pinsetx	#80,#pulse_pin			'1uS base time
    		setb	dira,#pulse_pin
    		pinsety	#3,#pulse_pin			'start pulse 3uS length
    
    or this way for same result
    		pinsetm	#_pulse,#pulse_pin
    		pinsetx	#1,#pulse_pin			'12.5nS base time
    		setb	dira,#pulse_pin
    		pinsety	#240,#pulse_pin			'start pulse 3uS length (240 x 12.5nS = 3uS)
    
    
    same applies to transition mode,etc.
    Great, thanks - Wow, not quite what I extracted from establishes a base period in clock cycles which forms the empirical high and low times.
    Reading again, I think the docs suffer from too much cut and paste...

    What does X=0 do ?

    I think also not quite the same result, as the tPW is the same, but #240 case will generate immediately, whilst #80,#3 case, will wait until next /80 rollover, before starting the pulse.


    From your example, Pulse is really a one-shot pulse, with Prescaler.
    Pulse Formula is tPW = Y * X/(SysClk),
    Shortest pulse is X=1,Y=1 => 1/SysCLK
    Longest is ( @80M) ((2^32-1)*(2^16-1)/80M)/60/60 = 977.3287558 hours ?


    same applies to transition mode,etc.

    Transition mode, I think is not quite the same, that is more Counted Pin Toggle ?

    The Prescaler sets Pin toggle (ie I think the comment establishes a base period in clock cycles which forms the empirical high and low times. relates better to Transition (toggle) mode.

    Pin.t = X/SysCLK // Toggle rate, repeat Frequency is SysCLK/2*X
    Number of toggles done = Y
    Taking those register values above, 80 & 3 would
    a) wait for next /80 rollover
    b) Toggle the pin 3 times, on each rollover
    and /1, /240 would instead output 120 Cycles of 40MHz ?


    Is this correct ?
    During reset (DIR=0), IN is low, the output is low, and Y is set to zero.
    as unlike Pulse, in Transition (toggle) mode, you ideally want to preserve the pin level

    Is there any way to set Toggle mode to continuous (not counted) ?
  • Cluso99Cluso99 Posts: 18,069
    edited 2016-04-14 03:23
    Chip,
    Please ignore!
    I just read the Smart Pins and I am going to give it a go with a single cog at 80MHz and see where I get up to :)

    Chip,
    Is there any possibility of getting 2 cogs in a DeNano and at 96MHz ???
    Please only do this if it is easy and quick.

    Here is what I would be trying to do...

    One cog would be either sniffing USB, then later modified to use the smart pins to do the same function as sniffing.

    The second cog would be decoding and sending the info serially to the PC via the smart pin UART.

    Once this works, I can then start making the first cog handle the USB protocol using the smart pins. The second cog would become a debugger sending info to the pc.

    Only 4 smart pins required.

    In this scenario there are lots of things that are not required and could be removed (cordic already gone, multiply/divide, streamer, DAC, etc) to maybe squeeze 2 cogs in there???

    I also have a BeMicro CV (5CEFA2F23C8N) if that is any easier.
  • jmg wrote: »
    I think also not quite the same result, as the tPW is the same, but #240 case will generate immediately, whilst #80,#3 case, will wait until next /80 rollover, before starting the pulse.
    That's correct but consider this scenario.
    In the #80,#3 example the delay before pulse start(rollover) is based from when the PINSETX(set base) instruction was issued to the PINSETY instruction. If a WAUTX #60 was issued after the PINSETX the PINSETY instruction starts a lot earlier.
    Here are three smartpins setup in PULSE mode and the capture of the result.
    		pinsetm	#_pulse,#pulse_pin
    		pinsetx	#1,#pulse_pin			'1uS base time
    		setb	dira,#pulse_pin
    		pinsety	#240,#pulse_pin			'start pulse 3uS length
    
    		pinsetm	#_pulse,#pulse_pin2
    		pinsetx	#80,#pulse_pin2			'1uS base time
    		setb	dira,#pulse_pin2
    		pinsety	#3,#pulse_pin2			'start pulse 3uS length
    
    		pinsetm	#_pulse,#pulse_pin3
    		pinsetx	#80,#pulse_pin3			'1uS base time
    		setb	dira,#pulse_pin3
    		waitx	#60
    		pinsety	#3,#pulse_pin3			'start pulse 3uS length
    
    

    Maybe the PINSETY command could be modified to iniate a rollover for deterministic timing of pulse start?


    1024 x 768 - 88K
  • deleted.
  • jmgjmg Posts: 15,173
    edited 2016-04-14 04:09
    Cool plots, a couple of delays seem not quite where expected ?

    The SW fall-thru time is shown as pulse_pin -> pulse_pin2,
    but the next set of SAME opcodes, seem to take longer
    pulse_pin2 -> pulse_pin3,

    looks to have waited until after pulse_pin2 started ?
    Is there a blocking opcode here ?

    I would expect pulse_pin3, to appear before the 80c delay on Pulse#2 ?

    I think WAITX is not related to PINSETX, but merely waits N SysCLKs ? (cannot find it in DOCs, apart from one code line)
    (If it does Wait N SysCLKs, WAITX could do with a rename to avoid confusing it as some polling X opcode ?)

    As a WAIT N, I would expect it to never decrease time, but to increase time in a stair-case manner.
    (ie in quanta of 80n for prescaler = 80)
    ozpropdev wrote: »
    Maybe the PINSETY command could be modified to iniate a rollover for deterministic timing of pulse start?
    It depends on the use, in some cases, that would be good, but in others with a prescaler, you really do want absolute edge align.
    (ie no change of prescaler phase)

    With both a prescaler and a Pulse width, this mode seems to have a lot of dynamic range.

    Maybe a PINSETX option could be to re-load X, so anyone wanting to control edge phase, could issue PINSETX ?
    Without a reload, a change in prescaler, would not give the expected change in pulse, as the first-overflow, would be indeterminate.

    Can that be an option ?

    Addit: Actually, with a prescaler and a Pulse width, even something simple, quickly gets complex.
    Users may expect the first pulse to be SW defined, but ones thereafter to be HW Edge aligned (UARTS are like this)
    In the plots above, it looks like XStarts on load, but that means Load Y some cycle later, needs to wait the rest of 80N for the next load.
    - a delayed leading edge results.

    Maybe the rule is, if you want exact edge control, you use X=1?

  • @jmg
    WAITX #60 simply waits 2+60 clocks (Adjustable NOP)
    Don't worry too much about the delays between the #1,2,3 plots.
    The point of interest is the delays from PINSETY to pulse start.

  • jmgjmg Posts: 15,173
    ozpropdev wrote: »
    @jmg
    WAITX #60 simply waits 2+60 clocks (Adjustable NOP)
    I think that needs a re-name then, to avoid the X already in other opcodes.

    ozpropdev wrote: »
    Don't worry too much about the delays between the #1,2,3 plots.
    I always worry about delays that are unexpected :)
    Can you explain why PinSet 3 took so long ? (The plot is from this code?)
  • jmg wrote: »
    I always worry about delays that are unexpected :)
    Can you explain why PinSet 3 took so long ? (The plot is from this code?)
    The WAITX instruction in between the PINSETX and PINSETY causes the delay.

  • jmgjmg Posts: 15,173
    ozpropdev wrote: »
    jmg wrote: »
    I always worry about delays that are unexpected :)
    Can you explain why PinSet 3 took so long ? (The plot is from this code?)
    The WAITX instruction in between the PINSETX and PINSETY causes the delay.
    How do you derive the plots you gave ?
    Looking closely, there seem to be signals not in the code above ?

  • cgraceycgracey Posts: 14,155
    ozpropdev wrote: »
    jmg wrote: »
    I think also not quite the same result, as the tPW is the same, but #240 case will generate immediately, whilst #80,#3 case, will wait until next /80 rollover, before starting the pulse.
    That's correct but consider this scenario.
    In the #80,#3 example the delay before pulse start(rollover) is based from when the PINSETX(set base) instruction was issued to the PINSETY instruction. If a WAUTX #60 was issued after the PINSETX the PINSETY instruction starts a lot earlier.
    Here are three smartpins setup in PULSE mode and the capture of the result.
    		pinsetm	#_pulse,#pulse_pin
    		pinsetx	#1,#pulse_pin			'1uS base time
    		setb	dira,#pulse_pin
    		pinsety	#240,#pulse_pin			'start pulse 3uS length
    
    		pinsetm	#_pulse,#pulse_pin2
    		pinsetx	#80,#pulse_pin2			'1uS base time
    		setb	dira,#pulse_pin2
    		pinsety	#3,#pulse_pin2			'start pulse 3uS length
    
    		pinsetm	#_pulse,#pulse_pin3
    		pinsetx	#80,#pulse_pin3			'1uS base time
    		setb	dira,#pulse_pin3
    		waitx	#60
    		pinsety	#3,#pulse_pin3			'start pulse 3uS length
    
    

    Maybe the PINSETY command could be modified to iniate a rollover for deterministic timing of pulse start?


    How about using OUT to gate the pulse activity?
  • I simply set a IO pin high before the PINSETY and the capture grabs that too. :)
    		setb	outa,#marker3
    		pinsety	#3,#pulse_pin3			'start pulse 3uS length
    
  • jmgjmg Posts: 15,173
    cgracey wrote: »
    How about using OUT to gate the pulse activity?
    How do you mean 'gate the pulse activity' ?

    This mode could benefit from a means to launch many pins at the same time.
    eg Suppose someone wants 5 pins with pulses of 1,2,3,4,5us, all starting on the same SysCLK, how do they do that ?

    This mode seems to have dynamic range to burn, so the rule of use X=1 for critical edge control seems ok, for single pin leading edge delay issues ?

  • cgraceycgracey Posts: 14,155
    edited 2016-04-14 05:14
    Rayman wrote: »
    P0..P15 stay at $60E5 during the entire first "IN" packet...

    Switches to $64E5 during two EOS clock cycles at end of packet then goes back to $60E5

    Later, I get $60E5 for a while then $10E5 then $9008 then $1008 and these are in 8-bit bunches...

    There should be a lot more varied activity than that. Bit 6 of the USB status indicates a bitstuff error, possibly. It looks like the baud is not correct. Bit 4 is never high, indicating no start-of-packet. Looks like a baud rate problem.
Sign In or Register to comment.