Shop OBEX P1 Docs P2 Docs Learn Events
Working full-speed (12 Mb/s) bit-banging USB Host controller — Parallax Forums

Working full-speed (12 Mb/s) bit-banging USB Host controller

scanlimescanlime Posts: 106
edited 2012-11-19 15:03 in Propeller 1
This is something I've been wanting to try for a while, but I finally had an excuse...

I've been wanting to build more devices that can communicate wirelessly. Sensors, ambient information displays, that sort of thing. To reduce the infrastructure needs, I'd like to use Bluetooth, or preferably Wifi. Problem is: I want these things to be cheap, and it's still fairly expensive to buy a Bluetooth or Wifi adapter that's microcontroller-friendly. I'd much rather stick a $5 USB bluetooth dongle on my Propeller and have a solution with simple/cheap hardware and software which is merely not impossible to write [noparse]:)[/noparse]

Anyway.. I'm still working on writing USB class drivers for it, but I have a working full-speed host controller. So far it supports Control, Bulk IN/OUT, and Interrupt IN transfers. There are a couple simple demos included: Device enumeration and descriptor parsing, a very simple HID demo, and an even simpler mass storage demo.

As you'd expect, there is a huge list of caveats for something that pushes the limits of the Propeller and the USB spec to this extent.. It uses four cogs, requires overclocking the Prop to 96 MHz, and even though the line rate is 12 Mb/s the actual usable data throughput is significantly lower.

But, this lets you talk to a lot of fun new peripherals that were previously unavailable to the Propeller. So it should be fun [noparse]:)[/noparse]

The hardware is really simple: Four resistors and a USB socket. If you try it out, let me know how it goes. Compatibility with different devices still isn't perfect. It works with most of the devices I've tried it with, but some don't work at all, and some work intermittently. But on the devices it does work with, transfers seem to be quite reliable.

My next goal is to write a simple proof-of-concept USB storage class driver ('cuz why not?) then see if I can get Bluetooth working.

--Micah

Post Edited (Micah Dowty) : 4/6/2010 6:30:59 AM GMT
«13456

Comments

  • heaterheater Posts: 3,370
    edited 2010-03-31 08:31
    It's a constant source of amazement to me. The number of things it's obviously beyond the Props capabilities or too hard to do that end up getting done anyway. Excellent work.

    Unfortunately I don't have a project that can spare 4 COGs for the addition of USB host.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-03-31 09:20
    Micah,
    Congratulations, this is great news indeed. Even if we have to sacrifice 4 cogs it is still excellent news that it can be done.
    FWIW, the prop can be overclocked reliably to 104MHz (6.5MHz xtal*16) with the correct layout and I am soon to prove 108MHz (13.5MHz xtal*8).

    I am sure there are ways to speed things up. Kuroneko is excellent with counters so he may have some ideas.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
  • TonyWaiteTonyWaite Posts: 219
    edited 2010-03-31 09:38
    Congratulations!

    Another barrier smashed!

    T o n y
  • Toby SeckshundToby Seckshund Posts: 2,027
    edited 2010-03-31 11:33
    Indeed, very well done. Many others just said it can not be done.

    Now it will be interesting to see what will play nicely.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Style and grace : Nil point
  • Ahle2Ahle2 Posts: 1,179
    edited 2010-03-31 12:30
    This is great news! [noparse]:)[/noparse]
    It will open up a lot of possibilities.
  • Bill HenningBill Henning Posts: 6,445
    edited 2010-03-31 13:19
    Excellent work!

    The only down side I can see is that it uses four cogs - however for some applications that is fine, and one can always add another Propeller...
    Micah Dowty said...
    This is something I've been wanting to try for a while, but I finally had an excuse...

    I've been wanting to build more devices that can communicate wirelessly. Sensors, ambient information displays, that sort of thing. To reduce the infrastructure needs, I'd like to use Bluetooth, or preferably Wifi. Problem is: I want these things to be cheap, and it's still fairly expensive to buy a Bluetooth or Wifi adapter that's microcontroller-friendly. I'd much rather stick a $5 USB bluetooth dongle on my Propeller and have a solution with simple/cheap hardware and software which is merely not impossible to write [noparse]:)[/noparse]

    Anyway.. I'm still working on writing USB class drivers for it, but I have a working full-speed host controller. So far it supports Control, Bulk IN/OUT, and Interrupt IN transfers. There are a couple simple demos included: Device enumeration and descriptor parsing, a very simple HID demo, and an even simpler mass storage demo.

    As you'd expect, there is a huge list of caveats for something that pushes the limits of the Propeller and the USB spec to this extent.. It uses four cogs, requires overclocking the Prop to 96 MHz, and even though the line rate is 12 Mb/s the actual usable data throughput is significantly lower.

    But, this lets you talk to a lot of fun new peripherals that were previously unavailable to the Propeller. So it should be fun [noparse]:)[/noparse]

    The hardware is really simple: Four resistors and a USB socket. If you try it out, let me know how it goes. Compatibility with different devices still isn't perfect. It works with most of the devices I've tried it with, but some don't work at all, and some work intermittently. But on the devices it does work with, transfers seem to be quite reliable.

    My next goal is to write a simple proof-of-concept USB storage class driver ('cuz why not?) then see if I can get Bluetooth working.

    --Micah
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.mikronauts.com E-mail: mikronauts _at_ gmail _dot_ com 5.0" VGA LCD in stock!
    Morpheus dual Prop SBC w/ 512KB kit $119.95, Mem+2MB memory/IO kit $89.95, both kits $189.95 SerPlug $9.95
    Propteus and Proteus for Propeller prototyping 6.250MHz custom Crystals run Propellers at 100MHz
    Las - Large model assembler Largos - upcoming nano operating system
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2010-03-31 14:36
    I like the idea of using cheap usb bluetooth dongles.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" 16:9 LCD Composite video display, eProto for SunSPOT, PropNET, PolkaDOT-51
    www.tdswieter.com
  • jazzedjazzed Posts: 11,803
    edited 2010-03-31 15:21
    @Micah

    Thanks for taking up this challenge. Being able to use cheap dongles instead of costly special modules is definitely worth losing COGs. It would be sweet if Propeller has room left for a port of a linux USB host driver for one of those cheap-o WIFI dongles ....

    Ooo-rah!
    Added: Hope this isn't an April Fool[noparse]:)[/noparse] Doesn't look like one.

    Post Edited (jazzed) : 3/31/2010 3:37:59 PM GMT
  • scanlimescanlime Posts: 106
    edited 2010-03-31 16:08
    Thanks, everyone [noparse]:)[/noparse]

    @jazzed: Not an April fools, though that would have been hilarious!

    Regarding the four cogs- there might be ways to reduce this, or at least to repurpose these cogs for other things most of the time. Only one cog is needed to transmit, but I'm using two interleaved cogs for receive, and one just to send ACK packets at exactly the right time.

    It would be possible to go to 1 receive cog rather than 2, if you're okay with limiting the maximum received packet size to what will fit in cog memory. The interleaving is necessary so I have time to stream the data back to hub memory.

    There also might be a better way to do ACKs, so I don't need a separate cog. The main reason for that is that when I need to send an ACK, the other cogs are all busy- the RX cogs haven't necessarily detected end-of-packet yet (they only get a chance once every 32 bits) and the TX cog is busy babysitting the RX cogs.

    It would be possible to have the TX cog send the ACK, but I'm using waitpeq to find the end-of-packet condition- so if the packet never arrives, we're stuck. But I could have the RX cogs take responsibility for waking up the TX cog after a timeout...

    That might work. I'll try to remember to give this a shot, it might reduce the number of cogs by 1 at least. Only downside I can see is that the ACK code would take up space in the TX cog that could be used for transmit buffer, so the max transmitted packet size will be smaller.

    --Micah
  • PhilldapillPhilldapill Posts: 1,283
    edited 2010-03-31 16:14
    Micah - No, an april fools joke of this magnitude would be down right mean. There are sooo many people on this forum that have dreamed of a USB Host controller in the propeller, only to be told that it's impossible. If you can get a USB thumb drive to work fairly reliably with this, I'm sure you will have people bowing at your feet.
  • KyeKye Posts: 2,200
    edited 2010-03-31 17:01
    Why not just support low speed USB? Then you should be able to fit everything within one cog.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • scanlimescanlime Posts: 106
    edited 2010-03-31 17:12
    Kye said...
    Why not just support low speed USB? Then you should be able to fit everything within one cog.

    That would work for low-speed devices only. All high-speed (USB 2.0 480 Mb/s) and super-speed (USB 3.0 5 Gb/s) devices still have backward compatibility with USB 1.1 host controllers in 12 Mb/s full-speed mode. So, a low-speed host controller would work with very few devices (mostly mice and keyboards) whereas a full-speed host controller will work with the vast majority of USB devices.

    If someone combined both a full-speed and low-speed host controller in one module, we'd have a fairly complete USB 1.1 controller that theoretically would work with any USB device. If there's a good reason to do this, it shouldn't be too hard. The same transmitter can be used with a lower clock rate. And a much simpler receiver cog would work. The rest of the code can be shared between both speeds.

    --Micah
  • jazzedjazzed Posts: 11,803
    edited 2010-03-31 17:36
    Micah Dowty said...
    but I'm using waitpeq to find the end-of-packet condition- so if the packet never arrives, we're stuck ...
    I've found using a 2 instruction test loop is often just as effective as using waitpeq. Depends on how long the incoming event is available of course.
  • scanlimescanlime Posts: 106
    edited 2010-03-31 17:41
    jazzed said...
    Micah Dowty said...
    but I'm using waitpeq to find the end-of-packet condition- so if the packet never arrives, we're stuck ...
    I've found using a 2 instruction test loop is often just as effective as using waitpeq. Depends on how long the incoming event is available of course.

    But that will give you a pretty large and variable latency of 8 to 16 cycles, right? I think waitpeq gives you single-cycle resolution.

    But yeah, I probably overdesigned that. I was trying to make the ACKs really robust so I didn't have to worry about debugging them and everything else at the same time- but it could be that it's okay to tolerate a little bit higher latency.

    --Micah
  • jazzedjazzed Posts: 11,803
    edited 2010-03-31 18:17
    If I understand it correctly:
    A waitpeq can take up to 15 cycles (7 in your example) to detect a condition less than 4 (1???) to exit.

    ' according to the data sheet, either of these would takes 8 cycles to detect and exit.
    cmp cond,ina wz
    if_nz jmp $-1 ' 8 cycles if no jump ... except that it's a nop when cond equal ina
    cmp cond,ina wz
    if_nz djnz timeout, $-1 ' 8 cycles if no jump ... except that it's a nop when cond equal ina
    
    


    From my experience, the 2 methods are equivalent, except that timeout latency is more and a pulse < 8 clocks will be missed.

    Post Edited (jazzed) : 3/31/2010 7:29:21 PM GMT
  • Bill HenningBill Henning Posts: 6,445
    edited 2010-03-31 20:02
    You know what would be perfect?

    A low speed host (1.5mbps) that worked at 80,96 and 100MHz, and supported USB keyboard and USB mouse in as few cogs as possible - ideally one cog.

    I know... I am dreaming... probably not feasible.
    Micah Dowty said...
    This is something I've been wanting to try for a while, but I finally had an excuse...

    I've been wanting to build more devices that can communicate wirelessly. Sensors, ambient information displays, that sort of thing. To reduce the infrastructure needs, I'd like to use Bluetooth, or preferably Wifi. Problem is: I want these things to be cheap, and it's still fairly expensive to buy a Bluetooth or Wifi adapter that's microcontroller-friendly. I'd much rather stick a $5 USB bluetooth dongle on my Propeller and have a solution with simple/cheap hardware and software which is merely not impossible to write [noparse]:)[/noparse]

    Anyway.. I'm still working on writing USB class drivers for it, but I have a working full-speed host controller. So far it supports Control, Bulk IN/OUT, and Interrupt IN transfers. There are a couple simple demos included: Device enumeration and descriptor parsing, a very simple HID demo, and an even simpler mass storage demo.

    As you'd expect, there is a huge list of caveats for something that pushes the limits of the Propeller and the USB spec to this extent.. It uses four cogs, requires overclocking the Prop to 96 MHz, and even though the line rate is 12 Mb/s the actual usable data throughput is significantly lower.

    But, this lets you talk to a lot of fun new peripherals that were previously unavailable to the Propeller. So it should be fun [noparse]:)[/noparse]

    The hardware is really simple: Four resistors and a USB socket. If you try it out, let me know how it goes. Compatibility with different devices still isn't perfect. It works with most of the devices I've tried it with, but some don't work at all, and some work intermittently. But on the devices it does work with, transfers seem to be quite reliable.

    My next goal is to write a simple proof-of-concept USB storage class driver ('cuz why not?) then see if I can get Bluetooth working.

    --Micah
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.mikronauts.com E-mail: mikronauts _at_ gmail _dot_ com 5.0" VGA LCD in stock!
    Morpheus dual Prop SBC w/ 512KB kit $119.95, Mem+2MB memory/IO kit $89.95, both kits $189.95 SerPlug $9.95
    Propteus and Proteus for Propeller prototyping 6.250MHz custom Crystals run Propellers at 100MHz
    Las - Large model assembler Largos - upcoming nano operating system
  • HannoHanno Posts: 1,130
    edited 2010-03-31 20:18
    Great work Micah! I would love to be able to stick a "DealExtreme" $2(including worldwide shipping!) bluetooth dongle: www.dealextreme.com/details.dx/sku.11866 on the Propeller. Opens up many options!

    You win an ultimate license for 12blocks or viewport if you can get it done!
    Conditions: I can communicate to/from the Propeller at 100kbps+ with just some passives and a USB bluetooth dongle. 4 cogs is fine, overclocking is fine, limits on datasize is fine, code is MIT license)
    Hanno

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Co-author of the official Propeller Guide- available at Amazon
    Developer of ViewPort, the premier visual debugger for the Propeller (read the review here, thread here),
    12Blocks, the block-based programming environment (thread here)
    and PropScope, the multi-function USB oscilloscope/function generator/logic analyzer
  • jazzedjazzed Posts: 11,803
    edited 2010-03-31 20:57
    It seems that Micah has created an "enabling technology" that allows others to produce on the growing wish list. We shouldn't rely on him for everything else too [noparse]:)[/noparse] If I wasn't knee deep in something else now, I would contribute.
  • TubularTubular Posts: 4,705
    edited 2010-03-31 21:00
    Micah, outstanding work, congratulations! This really opens up a whole new world of cheap expandability to the prop.

    Thankyou also for commenting the code so well, and more than that, adding a great background preamble at the start

    tubular
  • RaymanRayman Posts: 14,762
    edited 2010-03-31 21:46
    Cool! What kind of things can I host with this?
    Have you been able to host any devices yet?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm

    My Prop Products:· http://www.rayslogic.com/Propeller/Products/Products.htm
  • scanlimescanlime Posts: 106
    edited 2010-03-31 21:51
    Rayman said...
    Cool! What kind of things can I host with this?
    Have you been able to host any devices yet?

    So far I've tried it with HID, storage, and bluetooth devices- but I just started writing the actual drivers, so right now it's a bit too low-level to use for an application. But anyone who's interested in writing device drivers should be able to pick up this host controller implementation and get started [noparse]:)[/noparse] I was planning on doing a really basic storage and bluetooth driver myself, but if there's a different device class you're interested in, I'd encourage you to try writing your own driver.

    It should work with any full-speed devices that use Control, Bulk and Interrupt transfers.

    So far it has:
    - No-data control transfers
    - Control reads
    - Interrupt IN (read)
    - Bulk IN (read)
    - Bulk OUT (write)

    I plan to add control writes and interrupt OUT, but haven't had a need so far.

    Isochronous (for audio/video streaming) is theoretically possible, but I doubt the performance will be good enough for it to be useful. Also, the SOF markers I'm generating currently have fake frame numbers. Non-isoc devices won't care, but some isoc devices might.

    --Micah
  • BaggersBaggers Posts: 3,019
    edited 2010-03-31 22:01
    Micah, outstanding work [noparse]:D[/noparse] this certainly does open up lots more things that the prop can do!
    And it would have been mean, yet VERY funny if it was an April fool, but I'm glad it's real [noparse]:D[/noparse]
    Well done! from the whole prop community, a great addition to it's list of things it can do.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    http://www.propgfx.co.uk/forum/·home of the PropGFX Lite

    ·
  • potatoheadpotatohead Posts: 10,261
    edited 2010-04-01 05:41
    Excellent!! Like has been said, great addition, and simple interface too. IMHO, the 4 COGs for robustness is a good overall balance. It's not hard to add a propeller to a project, and that leaves 4 COGs for a nice display, and perhaps some basic controller, keyboard, mouse I/O. It's a slam dunk!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Wiki: Share the coolness!
    8x8 color 80 Column NTSC Text Object
    Safety Tip: Life is as good as YOU think it is!
  • BradCBradC Posts: 2,601
    edited 2010-04-01 15:14
    Late to the party, but that's an awesome piece of work. Great job [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • mctriviamctrivia Posts: 3,772
    edited 2010-04-01 16:41
    i just ordered the blue tooth dongle hano linked. how can they ship for free and make money?

    if this will let me communicate with my laser keyboard i will be a happy camper. i can just imagine it. robot drives up and projects keyboard in front of you. type in some commands and it drives away.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Check out my brand new site.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2010-04-01 19:54
    This is just amazing. I can't wait to see what becomes of this as it matures and drivers for devices are made available!

    I agree 3 cogs would be nice, but if it sacrifices anything (function/reliability/etc.), 4 is a workable solution for most projects.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!

    Some of my objects:
    MCP3X0X ADC Driver - Programmable Schmitt inputs, frequency reading, and more!
    Simple Propeller-based Database - Making life easier and more readable for all your EEPROM storage needs.
    String Manipulation Library - Don't allow strings to be the bane of the Propeller, bend them to your will!
    Fast Inter-Propeller Comm - Fast communication between two propellers (1.37MB/s @100MHz)!
  • AribaAriba Posts: 2,690
    edited 2010-04-01 20:28
    Great work, Micah !

    I immediatly built the hardware on my Protoboard (I had a, USB-A jack from other thests on it), and tried it with
    several USB devices:
    - no luck with some USB-PICs which has a HID and a CDC firmware. The enumeration test always returns Error -1.
    - no luck with an FT232R on a PropPlug clone, there I get Error -10.
    - But then, with a cheap MP3 player, the enumeration was sucessful. It is a storage device, and so also the Storage test spin
    worked well. No Bulk Read/Write errors.
    - So I tried also an external USB harddisk, and the enumeration was successful. But my Propeller host has not enough
    power to drive the disk.

    All in all a promising result smile.gif


    Some toughts about reducing the needed cogs:

    As you already said, the Tx-cog can do the job of the ACK-cog. The EOF state is active for 2 bittimes, so a test without
    WAITPEQ should be possible. Here a untested code idea:
               mov       count,timeout
    :waiteop   test      maskboth,ina   wz     'sampled all 8 cycles
       if_nz   djnz      count,#waiteop        'EOF is 16 cycles (2 bittimes)
       if_nz   'Timeout error
       if_z     'send ACK
    
    maskboth      long      BUS_MASK
    timeout       long      ?                            
    
    


    If too much cog memory is occupied, why not hold the encoded USB packets in HubRAM ?

    A trick to get a timeout for WAITPEQ is to use a free pin and a cog counter. The counter outputs it's state at the pin,
    and the pin is also contained in the WATPEQ mask and state. When the counter times out, the pin is changed, and
    the WAITPEQ is aborted.

    Perhaps with this trick it is even possible that the Tx-cog can also do the job of one of the Rx-Cogs, and we end up with
    only 2 cogs.


    Thank you very much for releasing this

    Andy

    Post Edited (Ariba) : 4/1/2010 8:33:42 PM GMT
  • scanlimescanlime Posts: 106
    edited 2010-04-01 20:43
    Thanks for testing, Andy! Hopefully future releases improve compatibility with different USB devices.

    I also noticed a rather nasty bug in the original release a couple nights ago: I was using WORD[noparse]/noparse to read unaligned data in the VendorID/ProductID convenience functions. So the enumeration demo would return a bogus vendor/product ID. I fixed this in the Subversion repo, but I haven't cut a new release yet.

    I had a little bit of time to try moving ACK to the TX cog last night- I wrote some code that looked like it should work, but it didn't right away. The timing is pretty finicky, and I didn't have time then to hook up my logic analyzer. In the next couple days I should have a chance to reexamine it.

    If I can tolerate the extra latency in loading the video generator, I can send the ACK using a few waitvids. That'll use very little extra cog memory. If I do have to use a big unrolled loop to send the ACK, I might indeed have to move the TX buffer into hub memory. I liked keeping it in cog memory to make the encoder a bit more efficient, but all things considered it's probably not a big deal either way.

    I also might overlay some of the buffers on the hub memory that stores the cog code, just to save hub RAM. (This would preclude stopping/restarting the USB controller at runtime, though...) There are a lot of small things that can be done to optimize memory usage and encoding/decoding speed. I haven't really started to optimize this at all.. I posted it here the day after I got HID working reliably [noparse]:)[/noparse]

    @Hanno: Nice find on those cheap bluetooth dongles. I think I'll order a few, so I can make sure the driver works with them!

    --Micah
  • scanlimescanlime Posts: 106
    edited 2010-04-01 20:49
    This looks pretty promising too:

    http://www.dealextreme.com/details.dx/sku.24688

    802.11 adapter with an Ralink chip, for $10 [noparse]:)[/noparse]

    --Micah
  • scanlimescanlime Posts: 106
    edited 2010-04-02 05:09
    This post on the video generator was really useful:

    http://forums.parallax.com/showthread.php?p=845742

    I have the USB host apparently working in 3 cogs, using the video generator to send an ACK. It's an unholy awful hack, but it appears to work. Prior to this code executing, I set up vscl for 'turbo' speed (1 clock per bit) so that the first waitvid has a narrower range of latencies. The actual latency in sending an ACK doesn't have to be super-low, but there's a narrow window I have to hit. Too long and the device gives up on me, too short and I don't give my receiver enough time to detect the end of the previous packet.

                  ' Sync to video generator, emit ACK
                  waitvid   v_palette, v_idle               ' Sync to vid gen. at turbo speed
                  mov       vscl, vscl_value                ' Back to normal speed at the next waitvid
                  waitvid   v_palette, v_ack1               ' Start ACK after a couple idle cycles
                  mov       dira, #BUS_MASK               ' Take bus ownership during the idle
                  waitvid   v_palette, v_ack2               ' Second half of the ACK + EOP
                  waitvid   v_palette, v_idle               ' Wait for the ack to completely finish
                  mov       dira, #0                        ' Release bus
    
    ...
    
    ' Pre-encoded ACK sequence:
    '
    '    SYNC     ACK      EOP
    '    00000001 01001011
    '    KJKJKJKK JJKJJKKK 00JJ
    '
    '    waitvid: %%2200_1112_2122_1121_2121
    '
    ' This encoded sequence requires 40 bits.
    ' We encode this in two logs, but we don't start
    ' it immediately. Two reasons:
    '
    '   - We enable the output drivers immediately
    '     after sync'ing to the video generator, So
    '     there is about a 1/2 bit delay between
    '     starting to send this buffer and when we
    '     actually take control over the bus.
    '
    '   - We need to ensure a minimum delay between
    '     EOP and ACK of 8 cycles in order for the
    '     pseudo-EOP detector to work correctly.
    '
    '     There's a small but variable delay between
    '     the actual EOP and when we start clocking
    '     out this buffer, due to setup time, EOP
    '     detection latency, and waitvid latency.
    '     So we don't need to wait a full 8 cycles here.
    '
    '     (Currently we wait 6 bit periods.
    '      This may need to be tweaked)
                                
    v_ack1        long      %%2211212121222222
    v_ack2        long      %%2222222200111221
    
    



    Still testing and tidying this up, but expect the next version to need one fewer cog [noparse]:)[/noparse]

    --Micah
Sign In or Register to comment.