Shop OBEX P1 Docs P2 Docs Learn Events
Prop123_A9_Prop2_v7z Intermediate Release - 25 March 2016 - USB, improved serial — Parallax Forums

Prop123_A9_Prop2_v7z Intermediate Release - 25 March 2016 - USB, improved serial

cgraceycgracey Posts: 14,152
edited 2016-03-25 11:07 in Propeller 2
Here is the first-pass USB for the Prop123_A9 board.

The FPGA configuration file (16 cogs, 64 smart I/O pins):

https://drive.google.com/file/d/0B9NbgkdrupkHOXpYUURlVzE2X3M/view?usp=sharing

Updated documentation (see smart pin section):

https://docs.google.com/document/d/1Os88kYoLLpd9xo43U0i54eBIhcFCBOaMG7yKZUDWGWg/edit?usp=sharing


Here is the section for USB:
%11000 = USB host, low-speed

%11001 = USB host, full-speed

%11010 = USB device, low-speed

%11011 = USB device, full-speed


This mode requires that two adjacent pins be configured together to form a USB pair, whose OUTs will be overridden to control their output states. These pins must be an even/odd pair, having only the LSB of their pin numbers different. For example: pins 0 and 1, pins 2 and 3, pins 4 and 5, etc., can form a USB pair. They can be configured via PINSETM with identical D data of %1_110xx_1. Using D data of %0_110xx_1 will disable output drive and effectively create a USB ‘sniffer’. NOTE: in the current FPGA, there are no built-in 1.5k and 15k resistors, which the final silicon smart pins will contain, so it is up to you to insert these yourself on the DP and DM lines.


The upper (odd) pin is the DP pin. This pin’s IN is raised whenever a change of status occurs in the receiver, at which point a PINGETZ can be used on the lower (even) pin to read the status word. No PINSETX/PINSETY instructions are used for this pin.


The lower (even) pin is the DM pin. This pin’s IN is raised whenever the output buffer empties, signalling that a new output byte can be written via PINSETY. PINSETX is used on this pin to set the NCO baud rate.


These DP/DM electrical designations can actually be switched by swapping low-speed and full-speed modes, due to USB’s mirrored line signalling.


To start USB, clear the DIR bits of the intended two pins and configure them each via PINSETM. Use PINSETX on the lower pin to set the baud rate, which is a 16-bit fraction of the system clock. For example, if the main clock is 80MHz and you want a 12MHz baud rate (full-speed), use 12,000,000 / 80,000,000 * $10000 = 9830. Then, set the pins’ DIR bits. You are now ready to read the receiver status via GETPINZ and set output states and send packets via SETPINY, both on the lower pin.


To affect the line states or send a packet, use PINSETY on the lower pin. Here are its D values:


0 = output IDLE - default state, float pins, except possible resistor(s) to 3.3V or GND

1 = output SE0 - drive both DP and DM low

2 = output K - drive K state onto DP and DM (opposite)

3 = output J - drive J state onto DP and DM (opposite), like IDLE, but driven

4 = output EOP - output end-of-packet: SE0, SE0, J, then IDLE

$180 = SOP - output start-of-packet, then bytes, automatic EOP when buffer runs dry



To send a packet, first do a ‘PINSETY #$180,lowerpin’. Then, after each IN rise on the lower pin, do a ‘PINSETY byte,lowerpin’ to buffer the next byte (D[31:8] are ignored for bytes). The transmitter will automatically send an EOP when you stop giving it bytes.


There are separate state machines for transmitting and receiving. Only the baud generator is common between them. The transmitter was just described, above. Below, the receiver is detailed.


At any time, a PINGETZ can be done on the lower pin to read the current status of the receiver. The upper pin’s IN will be raised whenever a change occurs in the receiver’s status. The receiver’s status bits are as follows:


[31:16] <unused> - $0000

[15:8] byte - last byte received

[7] byte toggle - cleared on SOP, toggled on each byte received

[6] error - cleared on SOP, set on bit-unstuff error, EOP SE0 > 3 bits, or SE1

[5] EOP in - cleared on SOP, set on EOP

[4] SOP in - cleared on EOP, set on SOP

[3] SE1 in (illegal) - cleared on !SE1, set on 1+ bits of SE1

[2] SE0 in (RESET) - cleared on !SE0, set on 7+ bits of SE0

[1] K in (RESUME) - cleared on !K, set on 7+ bits of K

[0] J in (IDLE) - cleared on !J, set on 7+ bits of J



The result of a PINGETZ can be bit-tested for events of interest. It can also be shifted right by 8 bits to LSB-justify the last byte received and get the byte toggle bit into C, in order to determine if you have a new byte. Assume that ‘flag’ is initially zero:
        SHR     D,#8    WC      ‘get byte into D, get toggle bit into C

        CMPX    flag,#1 WZ      ‘compare toggle bit to flag, new byte if Z

IF_Z    XOR     flag,#1         ‘if new byte, toggle flag

IF_Z    <use byte>              ‘if new byte, do something with it


Here is an example program that does full-speed USB in and out on the same smart pin:
' USB demo program
' - outputs incrementing values and reads them back on different cogs
' - uses P31,P30 as USB pins
' - outputs receiver status onto P15..P0

dat		org			'cog0

		pinsetm	pm_usb,#31	'configure DP pin (passive)
		pinsetm	pm_usb,#30	'configure DM pin (the brain)
		pinsetx	baud,#30	'configure 12Mbps
		setbyte	dira,#$C0,#3	'enable smart pins 31,30

		pinsety	#3,#30		'set J state (like IDLE, but driven)

		coginit	#1,#@recv	'start receiver cog
		waitx	##1000		'allow receiver cog time to load

		pinsety	#$180,#30	'send SOP byte (msb must be set)

.wait		testb	ina,#30	wc	'wait for buffer emptied (lower pin)
	if_nc	jmp	#.wait

		pinack	#30		'ack lower pin

		pinsety	x,#30		'send byte
		add	x,#1		'increment byte

		jmp	#.wait		'loop


pm_usb		long	%1_11011_1	'USB device, full-speed
baud		long	9830		'12Mbps @80MHz
x		long	0		'output value


		org			'cog1

recv		mov	dira,##$FFFF	'enable output on p15..p0

.wait		testb	ina,#31	wc	'wait for byte received (upper pin)
	if_nc	jmp	#.wait

		pinack	#31		'ack upper pin

		pingetz	outa,#30	'get status into p15..p0

		jmp	#.wait		'loop

I'm aware of a bug that when the USB smart pins come out of reset, they send an EOP. I will fix this soon. This will need some remedy during reset.
«13456

Comments

  • Oops, left the A9 at work for the long weekend. What was I thinking

    Thanks Chip

  • cgraceycgracey Posts: 14,152
    Tubular wrote: »
    Oops, left the A9 at work for the long weekend. What was I thinking

    Thanks Chip

    I wish it was trivial to make more compilations for different boards, but this is the quick way to get these changes out. Once we have more confidence in this design, I'll do a general release and cover the DE0-Nano, etc.
  • Nice work Chip! :)
    BTW. I had success today getting sync. tx working @ 40M bits thru a FT2232H module... Cool!
  • Looking good Chip!
    1024 x 768 - 110K
    usb.jpg 110.4K
  • Zoomed in a bit....
    1024 x 768 - 86K
  • cgraceycgracey Posts: 14,152
    ozpropdev wrote: »
    Nice work Chip! :)
    BTW. I had success today getting sync. tx working @ 40M bits thru a FT2232H module... Cool!

    I wonder how good setup and hold are. That's fast!
  • cgraceycgracey Posts: 14,152
    ozpropdev wrote: »
    Zoomed in a bit....

    Why do the INs not match the OUTs?
  • Cluso99Cluso99 Posts: 18,069
    Fantastic work Chip. Way more than I was expecting.

    How soon can you do a de-nano or bemicrocv version?
    Personal preference is a de-nano since I haven't used the BeMicroCV at all.
  • cgracey wrote: »
    ozpropdev wrote: »
    Zoomed in a bit....

    Why do the INs not match the OUTs?

    The IN's are the INA P30/P31 states (Buffer empty / Status) and the OUT's are the actual smartpin P30/P31 pin states.
  • jmgjmg Posts: 15,173
    ozpropdev wrote: »
    Nice work Chip! :)
    BTW. I had success today getting sync. tx working @ 40M bits thru a FT2232H module... Cool!
    Great :)
    Got some stats on that ? - what is the sustained thruput / equiv number of stop bits ?
    Did you use Async + Separate CLK, or Sync ?

  • jmg wrote: »
    Great :)
    Got some stats on that ? - what is the sustained thruput / equiv number of stop bits ?
    Did you use Async + Separate CLK, or Sync ?
    I used the sync mode fed by a local generated 40MHz clock (transition mode).
    384k x 11 bits (1 start,8 data,1 source & 1 stop) takes 108.13mS.
    I has a few attempts in async mode with a clock but had no joy.

  • jmgjmg Posts: 15,173
    edited 2016-03-28 03:29
    ozpropdev wrote: »
    jmg wrote: »
    Great :)
    Got some stats on that ? - what is the sustained thruput / equiv number of stop bits ?
    Did you use Async + Separate CLK, or Sync ?
    I used the sync mode fed by a local generated 40MHz clock (transition mode).
    384k x 11 bits (1 start,8 data,1 source & 1 stop) takes 108.13mS.
    I has a few attempts in async mode with a clock but had no joy.
    11.2635 bits is quite good at 40 MHz
    So that is manual Start of Clock, and then TX in Sync Slave mode (external Supplied Clock) ?
    Did this test the handshake line ?
  • Pin is set in sync. transmitter mode and clock is supplied by a pin in transition mode.
    The transition pin is loaded with a transition count of 384 * 1024 * 11 *2
    The exact amount of clocks for the block size. No extra stop bits are added.
    One continual stream of bits @ 40MHz of block length. No handshaking.
    FT2232H is in Fast Serial mode and still using VCP mode at the PC end.
    in this mode no baud rate setting is required in the PC.
    i.e. PST works at baud rates greater than the 3000000 limit.

  • jmgjmg Posts: 15,173
    That's simple enough.
    Interesting, I wonder when the FT2232 needs handshake ?
    Maybe a smaller USB buffer in the PC would generate a handshake ?

    The clock counts should not actually matter ie >= as the FT2232H will idle and skip clocks at stop.

    There will be some systems (different HW) that need a certain number of CLKs per byte, and a handshake.
    If you recode to Test handshake and send >= 11 bits per byte, what does that slow to ?
    (my guess is the FT2232H needs a CLK to update the handshake, so a continual CLK would also work)
  • evanhevanh Posts: 15,915
    edited 2016-03-27 01:43
    [deleted]
  • cgraceycgracey Posts: 14,152
    edited 2016-03-27 19:37
    I've been working on smart pin reset behavior for all modes. This will eliminate glitches on normal-mode/smart-mode switchover. The USB smart pin circuit had this problem and I realized that the serial baud mode had the same potential. That's almost all fixed now, so I'll get a general update out in the next day, or two.

    I believe that the smart pin is pretty much complete after this reset fix. There is room for four more modes, but I think I will fill them by just adding modes to the existing function blocks. Any simple suggestions? Maybe some time-this-signal-to-that-signal kind of functions? This would just entail adding a bit of steering logic to the existing measuring block, for example.
  • jmgjmg Posts: 15,173
    edited 2016-03-27 22:52
    cgracey wrote: »
    Any simple suggestions? Maybe some time-this-signal-to-that-signal kind of functions? This would just entail adding a bit of steering logic to the existing measuring block, for example.

    Yes, Time-interval A-B is a common and useful requirement.

    Also being able to start/stop two cells on the same SysCLK edge, is also useful for Reciprocal Counters:

    One cell Captures time on every edge, the other captures EdgeTotals, and you need to be able to gate/arm both those captures, so that the two values read, are guaranteed to belong the the same Fin edge.
    I think SW enable alone cannot do that - it always has some annoying, finite aperture effect ?

    Here is an example
    Fi __/==\__/==\__/==\__/==\__/==\__/==\__/==\__/==\__/==\__/==\__/==\__
    Arm  _________________________///===============\_______________________
    dT ooooooooooooooooooooooooooooooooNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
    dC ttttttttttttttttttttttttttttttttTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
    Common Capture SysCLK              ^
    CaptureACK  _______________________/=========================== PIN signal ?
    Read                                    ^N         ^T  
    Arm = Dual Capture Enable Arm, capture both dT,dC ONCE on next Fi edge
    
    Once/OneShot is needed, as the reads of N and T are separated, and you do not want a new update in one, after the other is read.


  • cgracey wrote: »
    I believe that the smart pin is pretty much complete after this reset fix. There is room for four more modes, but I think I will fill them by just adding modes to the existing function blocks. Any simple suggestions? Maybe some time-this-signal-to-that-signal kind of functions? This would just entail adding a bit of steering logic to the existing measuring block, for example.

    In case you miss it in the other post, is there a need to have both TX/RX modes and an output enable? Could you simplify it to simply synchronous and asynchronous modes, then use the %D field to indicate whether you are doing TX or RX? I realize this would actually increase the number of empty slots, but having both the modes and %D seem a bit redundant.
  • jmgjmg Posts: 15,173
    Seairth wrote: »
    In case you miss it in the other post, is there a need to have both TX/RX modes and an output enable? Could you simplify it to simply synchronous and asynchronous modes, then use the %D field to indicate whether you are doing TX or RX? I realize this would actually increase the number of empty slots, but having both the modes and %D seem a bit redundant.
    Wouldn't that require the Tx mode to have implicit OE, which means you need to redefine Tx to OE ?
    That may have too much latency vs a more direct OE ?


  • Cluso99Cluso99 Posts: 18,069
    Great news Chip.
    Just keep the spare bits for perhaps a later extension. For now, all bases seem to covered quite well.
  • jmg wrote: »
    Seairth wrote: »
    In case you miss it in the other post, is there a need to have both TX/RX modes and an output enable? Could you simplify it to simply synchronous and asynchronous modes, then use the %D field to indicate whether you are doing TX or RX? I realize this would actually increase the number of empty slots, but having both the modes and %D seem a bit redundant.

    Wouldn't that require the Tx mode to have implicit OE, which means you need to redefine Tx to OE ?
    That may have too much latency vs a more direct OE ?

    I'm not quite sure I'm following. In case I've explained the situation badly, take a look at the following:
    'xxxx xxxx xxx xxxxxxxxxxxxx x			= other configuration stuff
    '			       1		= pin output enable: on, regardless of DIR
    '				 11100		= mode: synchronous transmit
    %xxxx_xxxx_xxx_xxxxxxxxxxxxx_x_1_11100_1
    
    'xxxx xxxx xxx xxxxxxxxxxxxx x			= other configuration stuff
    '			       0		= pin output enable: off, regardless of DIR
    '				 11101		= mode: synchronous receive
    %xxxx_xxxx_xxx_xxxxxxxxxxxxx_x_0_11101_1
    

    You will notice that the Output Enable is on (1) for TX and off for (0) for RX. I don't see a use case for disabling output for TX or enabling output for RX. Conversely, allowing the combinations can cause some hard-to-find bugs.
  • jmg wrote: »
    That's simple enough.
    Interesting, I wonder when the FT2232 needs handshake ?
    Maybe a smaller USB buffer in the PC would generate a handshake ?

    The clock counts should not actually matter ie >= as the FT2232H will idle and skip clocks at stop.

    There will be some systems (different HW) that need a certain number of CLKs per byte, and a handshake.
    If you recode to Test handshake and send >= 11 bits per byte, what does that slow to ?
    (my guess is the FT2232H needs a CLK to update the handshake, so a continual CLK would also work)
    When using a continuous clock in sync mode you have to be aware that the transmitter shifter wraps and continues to send the last packet sent.
    In the attached image you will see I send 6 packets and then the shifter repeats the last packet.
    Filling the shifter with all 1's (PINSETY ##-1,#pin) after the last PINSETY gets around this issue.
    As for handshaking, the fast serial mode only has FSDO,FSDI,FSCLK an FSCTS pins available,
    In my Tx only test FSCTS is not relevant.


    1024 x 768 - 102K
  • ozpropdevozpropdev Posts: 2,792
    edited 2016-03-28 02:18
    Adding to Seairth's comments, the same applies to modes like quadrature encoder mode.
    If output is enabled the smartpin does not operate.
    Maybe the lower bit of %MMMMM could become the OE control?
  • jmgjmg Posts: 15,173
    Seairth wrote: »
    You will notice that the Output Enable is on (1) for TX and off for (0) for RX. I don't see a use case for disabling output for TX or enabling output for RX. Conversely, allowing the combinations can cause some hard-to-find bugs.
    A use case I can think of is where you need to mix SW and HW serials.
    For example, JTAG is 2 bit for the TMS state engine part, but can be 1 bit SPI for most of the data.
    Here someone may bit-bash the 2 bit part, and use 1 bit (+ Length) control for data.
    In this case easy change over from SW to HW modes is beneficial.
    Extracting special cases of OE, can take more logic, and it is reasonably common in MCUs to require Port-mode setups
    (eg CMOS or Open Drain, and Pullup on/off, so OE is just another pin-mode instance)

  • jmgjmg Posts: 15,173
    edited 2016-03-28 03:32
    ozpropdev wrote: »
    When using a continuous clock in sync mode you have to be aware that the transmitter shifter wraps and continues to send the last packet sent.
    Ah, yes, I forget this is Sync mode, being cobbled into Async
    IIRC, you said you were unable to get Async to work ?
    Other MCUs can Async send at up to SysCLK/2, but do impose lower limits on Rx, for the sampling.

    ozpropdev wrote: »
    As for handshaking, the fast serial mode only has FSDO,FSDI,FSCLK an FSCTS pins available,
    In my Tx only test FSCTS is not relevant.

    I thought you were sending Data P2 -> PC direction ?

    FT2232H Data says this

    " 4.8.2 Incoming Fast Serial Data
    An external device is allowed to send data into the FT2232H if FSCTS is high."

    ie FSCTS is handshake for P2 -> FT2232H direction ?


    For other direction handshake from FT2232H -> P2, they expect you to Pause the FSCLK generation in P2.

    It's impressive the FT2232H seems to not need the handshake, at least in your tests.
    I wonder when the FT2232H does require the Sending device to wait ?
  • @jmg
    Confirming P2 -> PC is test data direction.
    As long as CTS is high before you start transmission the process zooms along nicely.
    As soon as transmission starts CTS is pulled low by FT2232H and remains low for the duration of the transmission.
    Polling CTS during transmission would appear to be meaningless.
    If polling was necessary during transmission this would limit my max speed of 40M bits as my tx SW loop is as tight as possible now .
  • jmgjmg Posts: 15,173
    ozpropdev wrote: »
    @jmg
    Confirming P2 -> PC is test data direction.
    As long as CTS is high before you start transmission the process zooms along nicely.
    As soon as transmission starts CTS is pulled low by FT2232H and remains low for the duration of the transmission.
    Polling CTS during transmission would appear to be meaningless.
    There must be some conditions where FT2232H needs to pause Tx for less than saturated Tx .
    If you read deliberately slowly at at PC end, does that force longer lows on FSCTS ?
    ozpropdev wrote: »
    If polling was necessary during transmission this would limit my max speed of 40M bits as my tx SW loop is as tight as possible now
    On some systems, handshake support will be required.
    If you do add a WAIT line, what does that add in time ?
  • cgracey wrote: »
    Maybe some time-this-signal-to-that-signal kind of functions? This would just entail adding a bit of steering logic to the existing measuring block, for example.

    Quadrature output from clock?

  • evanhevanh Posts: 15,915
    edited 2016-03-28 11:35
    Quadrature output from bottom two bits of counter. Lots more control options with NCO rate, counter count length and even possibility for phase arranging.

    Err, or does NCO already use the counter?
  • jmg wrote: »
    Seairth wrote: »
    You will notice that the Output Enable is on (1) for TX and off for (0) for RX. I don't see a use case for disabling output for TX or enabling output for RX. Conversely, allowing the combinations can cause some hard-to-find bugs.
    A use case I can think of is where you need to mix SW and HW serials.
    For example, JTAG is 2 bit for the TMS state engine part, but can be 1 bit SPI for most of the data.
    Here someone may bit-bash the 2 bit part, and use 1 bit (+ Length) control for data.
    In this case easy change over from SW to HW modes is beneficial.
    Extracting special cases of OE, can take more logic, and it is reasonably common in MCUs to require Port-mode setups
    (eg CMOS or Open Drain, and Pullup on/off, so OE is just another pin-mode instance)

    I still don't see what you are getting at. Suppose you were to keep the separate OE bit for those modes. You still have to call PINSETM to enable/disable the OE. At that point, how different would this be than simply turning the smart cell off altogether (i.e. PINSETM #1) when you want to disable? In fact, it seems this is exactly the approach you'd want to take for switching between HW and SW serial.

    It seems to me that the only reason OE would be useful is if it was actually controlling the pin output, but not the internal output state. In this case, you could conceivably still use the output of one smart cell for the input to another smart cell without actually outputting the first cell's value on a physical pin.

    Actually, now that I think about it, why have the OE bit at all? In every one of the smart modes listed, it's clear that the input or output is determined by the mode. And, for output modes, it seems to me that setting/clearing DIR achieves the same purpose as OE, without the need to call PINSETM (which is 10 clocks, as opposed to 2 clocks for DIR).

    So... here's my proposal:
    1. Make input/output determined by mode only. It should not be possibly to have an input mode that is driving the output of a pin.
    2. For output modes, make OE only control whether the output shows on the pin.
    3. Regardless of OE, the output state is available to other cells as inputs.
    4. Use DIR as OE for output modes (which is already possible now).

    If options 2 and 3 add too much logic, just get rid of the OE bit altogether. I'm sure Chip can come up with a use for that extra bit. :)
Sign In or Register to comment.