Embedded - 337: Not Completely Explode
Episode Date: July 16, 2020Kate Temkin (@ktemkin) explained USB: how to get started, general orientation, useful tools, and when you’d use it in embedded systems. Kate’s website is ktemkin.com. She works at Great Scott Gadg...ets. References for USB: USB in a Nutshell USB Complete by Jan Axelson USB Embedded Hosts: The Developer’s Guide by Jan Axelson USB Specification, Chapter 9: USB Device Framework USB Stacks we talked about: TinyUSB from Adafruit Lufa Cortex libopencm3 For the host side: libusb Open Source VIDs are available from Openmoko and Pid.codes Kate recently gave a talk about making USB accessible. Part of the talk was about Luna, an FPGA based USB multitool. Some open source FPGA tools: Symbiflow.github.io Yosys: http://www.clifford.at/yosys/
Transcript
Discussion (0)
Welcome to Embedded.
I am Alicia White.
I'm here with Christopher White.
Remember when we asked about USB and had to admit ignorance?
Well, happily, we have Kate Temkin on this week to help us with that.
Hi, Kate.
Thanks for correcting us.
Could you tell us about yourself?
Hi, so I'm Kate Temkin.
I describe myself sometimes as a hardware hacker.
I work for a company called Great Sky Gadgets.
We make things like the Ubertooth and the HackerF and GreatFat.
I do a lot of USB things lately,
lately being like the past four or five years.
And generally my goal is to make as much um of the stuff that is invisible to you the stuff that you really kind of have in fast protocols and in devices that you can't really
you can't really see a little signals i like to get all that stuff not just visible but to the
point where you can kind of reach out and grab it so i like to make things like usb and rf tactile neat i'm looking forward to scarves
usb scarves yeah no okay uh we want to do lightning round where we ask you short questions
and we want short answers and if we're behaving ourselves we won't ask how and why and of course
you have to turn it upside down are Are you ready? Mm-hmm.
How many USB cables are too many?
As soon as you can't fit them in whatever drawer is near your desk.
What's your favorite USB connector type?
Mini-A, Micro-B, Fluffernutter, C?
I'm going to say C, but as long as it's not B, it's good.
As long as it's not the big full-size square
one yeah what are the odds of plugging in a usb a connector the right way the first time depends
how much you've looked at it beforehand once you once you get really intimately familiar with the
machine you can kind of do it first time but if you're not aware of the orientation the cable is
in or the machine is in it's going to take you like three tries three yes that Yes, that's it. It takes three, even though there are only two ways.
Yes.
Right.
You plug it in once, you're sure you got it wrong.
You flip it and then you actually are wrong
and then you flip it back and you're right.
Do giraffes make sense?
They're on the borderline.
Favorite and least favorite ice cream flavor?
Hmm.
I really like spicy ice cream.
So there's a local place in Colorado that has all these different pepper flavored ice creams and they're fantastic.
They don't sound like they'd be good, but they are.
And I don't like just chocolate ice cream.
Okay. Well, this was a nice show.
Yeah. Thanks for talking to us.
Let's talk about USB.
Although ice cream could be its own show.
I haven't worked much with USB, just a little bit.
I've done a lot of UR and I2C and SPY,
but how hard could USB possibly be?
That depends what you're doing with USB. So USB is actually not that complicated once you get
a lot of the boilerplate out of the way. But finding out how to do all that stuff is difficult
because it's embedded in this giant specification. So if you want to do USB stuff and you have all
the like low level physical layer stuff taken care of you, it can be really, really easy to do USB. But if you have to go and implement everything from either actually going and flipping the
bits on an FPGA for USB, it can be challenging to get everything right.
And then if you're working with a vendor library, like one of the CMSIS ones on ARM, it can
be very difficult to get those to work correctly, because chances are someone who's engineered
that has done something not quite right or not for your use case.
But the CMSIS ones are the ones the vendors provide. Those are the easy path. Are you saying
don't take the easy path? It's not necessarily don't take the easy path,
but look at exactly what they're trying to do with those libraries when they give them to you.
Because a lot of times what they want to do is they want to give you a reference design
that's going to get you up and running really quickly.
And it may get you up and running really quickly in that environment and with exactly that setup.
And sometimes with some vendors that works, but with especially like the cheap little chips
like the Atmel SAMDs and the STM32s, those tend to have really interesting limitations on their USB that the vendor libraries don't really make apparent.
And because I'm just using it to get the example code running, and I don't know much about USB, I'm not likely to know where the corner cases are going to bite me. And generally, you're not necessarily, a lot of times when they do those
libraries, they're like, they are doing exactly the same thing you are, where they're getting that
exact example running. And they haven't been able to exhaustively test all of the different things
that you might want to do with it. So if you go and do something that's different, you might find
that there are assumptions in that USB stack that are either just things that they didn't, your application
is one that they never thought of, or that they're just paths that they never tested,
because they were able to get their demonstrations working, and then they never moved on from there.
When you're talking about USB, and you're looking at a new project, do you start from scratch,
or do you start from like the comp port or keyboard
device classes? So it usually depends on the individual project, but most of the time I
actually tend to avoid the different class devices unless I need something that I really
want to have one of those drivers
bound to because vendor requests so control requests the stuff that's not covered by any
of those classes stuff that's really vendor specific those are super super easy compared to
a lot of the rest of the stuff they require almost nothing but then don't I have to create
a custom driver how will how will my windows box or unix box talk to something that isn't standard
so the lucky thing is that there's actually nice user space drivers for those things so
like lib usb on especially like mac os and linux is very very easy to do things that are just poking
a usb device so if you don't need the speed of constantly being, reacting things really quickly,
if you can take a little bit of latency, then not being in the kernel makes it really, really nice
to work with things in the user land. And it's a little harder on Windows, because you have to go
and get the driver bound to lib USB. But after that, if you're just doing simple things, lib USB
and those kinds of user land drivers make it really really nice can you
quantify the the limitation like is it oh i wouldn't want to put uh something that had to
react in 100 milliseconds in user space or is it more like a difference between 10 milliseconds and
microseconds or so it really depends on the configuration but if you look at Linux, the scheduler on Linux has a finite granularity
that they just call hertz.
And that scheduler granularity is kind of,
like your process only gets scheduled so frequently,
and that granularity is kind of determining
how quickly you can respond.
So if you're down in the case where you really need no latency,
like you're going to be grabbing video
and you want to throw that up on the screen
as soon as you can, no lag.
That's the kind of place that it makes sense to be in the kernel.
But luckily, those kind of cases are
usually things where there's already a driver, like you're
doing a USB video class device.
So chances are, if you're just
spamming data and you want to just get it fast
and you don't necessarily care 100% about the latency,
you can just do
that stuff from the user LAN.
Stuff like HackerRF, stuff that does really high throughput software-defined radio stuff
that's just blasting out bits,
that stuff actually uses entirely user LAN drivers.
So there's not a kernel driver that's typically used for that.
Okay, that's what I was going to ask, because there's no throughput limitation,
it's just mostly latency.
No, as long as you do things correctly, there's very little in terms of throughput limitation,
because especially on USB 2, your throughput is tied to 48-ish megabytes per second anyway.
The theoretical maximum is like 53.
So with protocol overhead and the computer actually doing the scheduling,
you're probably not going to hit the point where you're really throughput limited in your process.
That's interesting because I was going to say, well, why don't I just use a serial port?
But if you're talking 48 megabytes per second, that's why I wouldn't use a serial port.
And then the thing is, if you want to use something that's serial port-like,
but still have that kind of throughput,
there's lots of stuff you can do that looks and acts a lot like a serial port,
acts a lot like a UART, but it's over USB.
So the USB has this thing called the communications device class,
which is the general class for things that let you use
telephones and ethernet and things like that. And one of the specific subtypes is called ACM,
which is for any abstract kind of control model device. One of the subcategories of that is
actually meant to talk to AT modems, like the old like Haze, like old AT modems, where you're
sending serial commands to a modem and it's responding.aze, like old AT modems, where you're sending serial commands
to a modem and it's responding.
Wow.
A lot of things just use that, say I'm an AT modem, and then wind up just using it as
a UART-ish device.
So essentially, you're lying into it and saying, I have a modem here, in order to get what
is effectively just a USB connection that your computer thinks of as a UART,
because it would normally use that UART to talk to a modem.
And the nice thing about that is it's not really...
It thinks your hardware is talking at a given baud rate,
but it doesn't necessarily need to talk to your hardware at that baud rate.
So you can spam all 48 megabytes per second to your device, and it counts on your
device to actually go and slow that down and put that out at the correct UART baud. And what that
means is if your device doesn't actually care about talking to UART, it can just take that
data as fast as you want. You can have something that from your computer side behaves like a UART,
but is actually going as, you know, pretty close to the full capacity of that usb bus so to do usb like
that i need to understand the computer side as well as the device side so if you're doing it with
a like a cdc driver that's the kind of thing where you don't need to understand the computer
side as much it shows up as a virtual com port on. Once you have the driver set up or on Linux or macOS,
it shows up either as like dev tty acm0
or like dev tty and the serial number on macOS.
So it looks to the computer side like a serial port
that just ignores your baud rate settings.
But on the device, you need to understand that it's USB.
But you said that we can do other things more direct things why why do the
more direct things instead of this acm that that seems fast problem solved so the the general case
reason that you don't want to do the stuff that's direct over like bulk is because there's no packet framing
over something like ttyacm there's no concept of like a command and a response whereas if you're
using the basic direct stuff you're using control requests those are the those are the mechanisms
that usb provides for doing things like getting the device's name, getting the device's vendor ID and product ID.
It lets you specify your own vendor-specific ones of those,
and those come framed as commands already.
And usually the USB stack you're running on your device
will go and say, here's a command with a few arguments.
Now I'm giving you a chance to either receive data or respond.
So you actually have this nice built-in kind of command framing.
So if you want to do something like, say, turn on these three LEDs,
turn on the I'm recording LED,
that's something that you don't have to worry about
figuring out how to packetize that, how to go and serialize your data,
take all the arguments, shove them into something like a struct,
and then unpack them on the other side.
They come to you as a command already.
You said USB stack, and we talked a little bit about CMSIS stacks.
What else is out there, and what do I expect from my embedded USB stack?
So I think my favorite one of these is called TinyUSB.
And TinyUSB is an it's an abstraction layer.
It's used by a lot of the little Adafruit circuit
Python boards.
And it is a really lightweight way to
get a bunch of pre-made
USB device types working
out of the box. And if you're one of the supported
processors, it's very nice to just kind of
like it gives you a blinky
essentially that with all the board support
packages and everything for that processor.
And if you have a board they support,
it's even easier because then you just,
you can literally run Blinky
without doing any platform setup whatsoever.
And like, that's lovely if you just want to get started
because you don't even have to think
about the USB as much there.
Like you can say, I want to be a virtual serial port
and it'll give you a function that's called
every time new data comes in as if you were a, know as if you were getting a ur interrupt and so that that kind of
thing can be really lightweight there are a couple other um usb libraries for various other things i
think uh like back in the day when avrs are really popular the standard usb library for that was
called lufa lightweight usb framework for avrs and then lib open sam3 has a
bunch of usb uh stuff if you're trying to use a cortex m like three or four and those sorts of
things are are large enough that they like support mass storage and stuff because i remember years
ago having trouble getting mass storage to work and uh it was always such a problem because you
know half the usb sticks wouldn't work for some reason.
So a lot of them do support what's called bulk-only transport,
which is probably the simplest way of doing mass storage.
Essentially, it gives you the equivalent of a UART in and a UART out,
and you exchange SCSI commands over that.
The downside of that is that you have to then handle
all the SCSI commands and everything.
So you get a block right, and you have to then handle all the SCSI commands and everything.
So you get a block right, and you have to go and handle that correctly.
And being able to do things like all the sense detects and get all the metadata up to the operating system correctly,
or whatever you have that USB device plugged into,
getting that stuff to be compatible is still a challenge,
even if the mass storage layer works for you correctly.
Do most of these stacks run on an operating system
or can I run them without an operating system?
Depends what you mean by operating system.
So from my perspective, an operating system
is more of a way of thinking about something
than an individual layer of software, right?
If I'm running an operating system,
whether it's a full-scale Linux or like an RTOS,
I'm thinking about that as something that
I am letting take responsibility away from me, right? And so if you want the full stack of things
to take responsibility away from you, you can work in your little section, then chances are you're
running some kind of operating system, right? And you're kind of in your thought process.
Whereas if you're going and writing every bit
of that and you're i've had projects that start off as just like i'm going to do this really
simple event loop and eventually you know a year later into the project has a scheduler and has
memory management and i've put all these individual pieces in at no point during that was i thinking
i'm writing an operating system but suddenly the whole thing kind of sneaks up on you and you're
like yeah okay well now that i have a scheduler and I have a heap and I have Malik and I have all these nice
things, I basically have written an operating system. And now that I'm porting it to a different
platform, I have the hardware abstraction layer and I've come full circle. I could have used an
RTOS to begin with and I would have been done with all of this. So whether or not you have an
operating system, I think depends on how you're using the software and using that stack.
If you let it do most of the stuff for you, I'd consider that having kind of an operating system underneath you.
I tend to want one when I'm looking at USB in part because I'm often using mass storage classes, which means I probably have a file system.
And at that point, I don't want to write all that
yes there is a really nice driver you can use called fat fs yes and if you then that takes a
lot of that away from you and i wouldn't like i wouldn't think of that as having an operating
system even though it is providing lots of services to me right but that is something that
you could kind of integrate into a larger operating system
or your operating system might provide
but again if that's the centerpiece
of what you're thinking
you're thinking I'm going to run this thing
atop of a driver like that
and really like that is
I'm just adding my application on top
then you're thinking about that as an operating system
I can give you an example of something
that definitively I think does not run
in an operating system
which is one of the things I've been working on lately is a project called Luna I can give you an example of something that definitively I think does not run in an operating system,
which is one of the things I've been working on lately is a project called Luna,
which is an FPGA-based USB stack.
And so you can actually run USB applications without what you consider a typical general-purpose processor at all.
So there's no microcontroller, there's no soft core, there's nothing like that.
I have a piece of hardware I've implemented that does an entire USB stack.
And that's all in hardware.
So then I think you'd be hard-pressed to say
that has an operating system
because there's nothing running sequences and instructions on there.
That makes sense, yes.
Okay, so back to USB as a standard. It doesn the fact that you have two wires and they're exchanging this data in this half
duplex way over those two wires. And then on top of it, you have the way packets are shaped. And
then on top of that, you have a set of protocols. And really, USB is designed to do the core spec.
It does three things. It handles the device's self-identification. So it lets you plug in
something and say, this is a printer, right? It gives you the ability to have some very basic data exchange.
So either control requests or essentially just taking data in a UART-like way and exchanging it back and forth.
Whether you have the operating system doing some scheduling for you or not, it's kind of essentially just data being passed back and forth. And then the third thing
it does is it provides all these
mechanisms for working with
USB hubs. Everything else
that's not
within those purviews, like your
head drivers and stuff, those are in USB
class specifications.
So they're kind of not in the core USB stack,
but kind of their expansions
of the specification allow you to say, this is the way we recommend you write a standard mass storage device.
And this is the way we're going to have operating systems implement drivers that you can talk to those operating system drivers.
Once you get to that level, that's where it really starts becoming very non-standard.
At the level below that where you're doing the control requests and bulk stuff,
it's a lot more standardized. That's interesting. I mean, I guess it has to be because when you're talking about high-speed signals, you don't get to be an individual as you implement high-speed
signals. Everybody needs to have it be the same style. I think the thing there is that when you want to do that kind of thing,
you build abstractions, right?
So if you want to have your layer of completely individual protocol,
what I'm going to do is I'm going to give you all these layers
where you have the physical layer and you have some basic protocol stuff,
and then I'll try to let you do whatever you want to atop all that high-speed stuff
without necessarily being aware of all of it.
So all that abstraction lets you do things like take your data
and shove it over an Ethernet port, right, and shove it over TCP and IP
and have it just come as essentially like a pipe to the other side, right,
or over USB, you can send data across a pipe and just have it come out.
And so the idea is not necessarily to make it so that there's a standard so that everyone has to talk exactly the same, but instead to give you kind of a standard foundation that everyone can talk about.
That does make it difficult when you have odd problems like a thumb drive working on one computer but not another or working when plugged into a hub but not when plugged in directly.
How, as an engineer designer, how do I avoid those corner cases that just frustrate people?
The best thing you can do is to find something that already works, that you know works well on a lot of different cases, and try to be as close to that as possible for two reasons.
One, it's going to have a lot of existing tests,
so hopefully people have run into those problems before.
But also there's kind of this effect
in a lot of these hardware protocol development layers
where instead of having the specification
be the only thing that's limiting behavior,
you also have what windows does
so if you if you take a usb device and plug it into windows and windows does things a specific
way then people will go and build devices they'll test it against the way windows does things call
it a day and then if linux does something by the spec but differently all those devices might not
wind up working on Linux. And then the
Linux developers have to go and figure out why that's happening. And eventually they start kind
of heading more towards the, well, this is the right way to do it, but also this is the way
Windows does it. So it's kind of the specification on top of a specification. That seems wrong,
really wrong. But I mean, it does happen with things that seem as straightforward as thumb drives. So
when you say find something similar, do you mean hardware similar, software similar,
application similar? The best case scenario is you can have something that is like, if you have
something that does exactly what you want in, you know, on existing hardware and software,
if you can take that, then that might be a more expensive solution for you, but you're going to save an engineering time, right? So in that trade
off, you can say, well, I'm not going to have to debug things if I have something that's almost,
or, you know, as close to exactly this thing as I can. Right. And that's one of the reasons why
the FTDI chips are so popular, is that you can get something that someone has already done all
the engineering on, and then build your abstraction on top of this thing that you know that talks serial atop this exact piece of hardware that
everyone winds up having and a lot of these different devices right you don't have to think
about all those details so if you don't want to be frustrated if you want to minimize your
engineering time like you're doing a one-off product you're better off staying with something
that is very close to the application you want to actually accomplish
there, the application you want to build towards there. It sounds like you're telling me to buy
my USB things instead of build them. And if you can, it really depends on the kind of thing that
you're looking for, right? There's always a trade-off in engineering. And if you're optimizing
for the least frustration possible, the best thing you can do is
to buy something that already works right and if that means that like people laugh about you know
buying a consumer product and getting a raspberry pi inside because you know to a lot of people that
seems like okay you're getting this whole big pre-made block and you know using that i don't
know people rationalize that as lazy or whatever but if you're producing a few of something and you already know that solution works, that can be a way to save on the non-recurring engineering cost of developing a product, even if it costs more for every product you make.
So I think there's actually a lot of validity in using solutions that are closer to kind of canned solutions or pre-made solutions.
How do I choose which USB stack or USB standard or spec or whatever it is?
USB 1.1, 2.0, C, 3, 4?
What are all of these and how do I decide what the latest shiny is versus what I really should be doing?
So you're going to ignore USB 1 and USB 1.1.
Don't even look at those because those are superseded by USB 2.
USB 2 contains all the stuff for USB 1.
So essentially everything that is in,
even if you have like a low speed or a full speed device,
those behaviors are still specified now in USB 2.
So choosing whether you want to do a lowspeed device, those behaviors are still specified now in USB 2. So choosing whether you want to do a low-speed device, a full-speed device, or a high-speed device then is going to depend on
your throughput requirements and what the hardware that you can get for a lower price can give you,
right? If I need to push through 30 megabytes per second, I'm not going to go for a full-speed device because a full-speed device can do 12 megabits per second, right?
But a high-speed device can do 480 megabits per second,
which winds up being 60 megabytes per second of actual signaling
and something like 53, after all your protocol,
overhead of 53 megabytes per second of, ideally,
of data that you can exchange where when you start
getting to requiring more than that then you start looking at usb3 um and then if you need stuff that
is even more than that or that has the capability to do things that you wouldn't normally do via
usb usb4 which i'll admittedly, that's relatively new. I'm not
super an expert on USB 4 yet, but the USB 4 packs a lot of other applications into the USB-C
connector. So things like being able to take a PCIe device and connect that via USB. If you're
one of the people who know that you need something like that you're going to look at usb4
the chances are if you're saying i have a little embedded thing that i want to connect you don't
have a reason to say that i want display port or pcie off the bat then you're probably looking at
either usb twos in low speed full speed or high speed or super speed or super speed in USB 3.0 or 3.1,
which is kind of the...
There was a naming convention of, like, USB 3.0
and then USB 3.1,
and then that wound up becoming, like,
super speed Gen 1, super speed Gen 2,
and they kind of made a mess of the naming conventions.
But all those kind of things
are basically different speed grades
under the USB 3.0 specification. Would you say the breakdown is kind of things are basically different speed grades under the USB 3.0 specification.
Would you say the breakdown is kind of, I need gigabits per second versus megabits per second?
If you're getting over hundreds of megabits, it's time to look at something more complicated like USB 3.0.
Yeah, if you're getting to the point where you need uh if you're getting the point where you really need to like push data as fast as you can um basically if you're a hard drive or you're a
like a solid state drive you're that kind of thing you're going to connect that via usb then you're
looking at usb3 if you're looking at something where you need to be able to get you know tens
of megabytes then you're looking at usb uh two is high speed. If you want something that's going to exchange
the high kilobytes of data,
then you're looking at USB full speed.
And if you want something that's going to give you events very rarely,
like a keyboard or mouse,
you're either going to be full speed or low speed,
depending on your power requirements.
And C is just the cable type, right?
C is the connector,
and it implies some things about the cable that
are connected to it but there's different cables that can go to the same connector
so if you look if you were to look at yes there are why is that so usbc has a reversible connector
right which means that it can never be upside down right theoretically if somebody does things
correctly then the cable can never be upside down you can plug theoretically. If somebody does things correctly, then the cable can never be upside down.
You can plug it in either way.
And the way they do that is by taking the connectors and putting them on both sides.
And in that row, there's the USB 2 connection, one USB 3 connection,
some what's called a sideband line,
which is just a line that you can use for whatever you want when you're not in USB mode.
And then there's these
communication lines that are used to negotiate like power delivery and those exist on both sides
of the device and theoretically like if i buy a cable i can buy a cable that is meant for high
speed it's meant for usb2 in which case it only has the two USB lines on one of the two sides implemented.
And then it's connected through on both sides of the cable.
And then the cable, the connectors themselves have the ability to identify which way they're
plugged in.
And it's the host computer's responsibility to go and say, okay, I'm either going to use
the top USB lines or the bottom USB lines.
So you wind up with a nice cheap cable
that only has one set of USB data lines connected
that is for USB 2.
And then you can have the super speed cable,
which theoretically is very similar,
except that it has the super speed lines populated,
which is another two pairs.
So you have a super speed transmitted
and a super speed received, two differential pairs for those. And then if you want to go
even further than that, the newer specs for USB allow you to communicate twice as fast
by using both the bottom and top connectors at the same time. So eventually you have cables that
have not just the top connectors or not just one side So eventually you have cables that have not just the top
connectors or not just one side populated, but
have both sides populated.
So now you have all these different kinds of cables that are all
connected to the same connector.
That explains my desk drawer.
Yes. And for additional
confusion, Thunderbolt is the same
connector.
Right, and used before all the other stuff that
sits over there, like the stuff that was
Thunderbolt 3 and all the alt modes, those are all over that same USB-C cable. So you can go and buy
a USB-C to A cable. That's one of the ways that you can have things hooked up. You can buy a USB-C
to Micro B cable. You can go and buy a USB-C to DisplayPort cable or USB-C to HDMI,
which winds up being HDMI over DisplayPort. Or you can buy a USB-C to audio cable. There's all
these things called alternate modes now that take the USB-C connector and use them in completely
different ways. So they try to do everything with this cable and this connector rather. And as a
result, you have a lot of possible cables that have that connector on the end.
Didn't someone say, hey, everybody, this is a terrible idea?
I have a different opinion.
I think it's a lot better, but it's also a lot worse.
That's two opinions.
So the thing is with that, it really depends on whose perspective you're looking from, right? If you want to have a single laptop that has eight ports that can all do all of these things It can be a fast USB device. It can be a really fast USB device.
It could be something that's connected that you would normally have like a sitting inside
plugged into a motherboard on a computer, like a PCIe device.
It can be your display out.
It can be your audio out.
It can be all kinds of things.
There's even a debug specification for that, where you plug in a cable that has a certain
special configuration, and then you just
get GPIOs out of it, assuming your device supports that. And it's not always GPIOs,
essentially whatever the designer wants to use those IO for. So all these things are over that
same connector. And it sounds great until you as an implementer are sitting there and saying,
okay, I want to make one of these connectors now.
How many of these things do I have to implement?
And then if you don't implement all of them,
then suddenly you have a laptop that has eight of the same ports,
of which some of them do video, some of them do charging,
some of them do USB in the really fast configuration.
And all the semantic meaning that was inside that connector is suddenly lost.
So you have a lot of convenience until you don't.
Yes.
Better and worse.
All right.
Well, and you said a host.
And usually when I think host, I think my laptop.
And as you were saying, I want,
ideally my laptop has a few ports and i can use whichever one is handiest but
with usbc actually since usb on the go it isn't always a computer that's the host sometimes
it's my device that's the host is that ever a good idea i I mean, I think it can be, because the USB signaling is very similar
between host and device,
and if you can do both, that can be nice.
One of the things that Apple introduced a while ago
when they introduced the Thunderbolt connector,
their overloaded DisplayPort connector
in the original ones,
was they had the ability to let you take a computer,
plug it in with that Thunderbolt cable to another computer,
and then boot it up essentially as a big flash drive.
So essentially take that hard drive
and make it accessible for another machine,
which sounds like it's a really nice thing to have around, right?
And now in their modern ones,
you can actually take the old laptop
that you normally throw out and use it as a display, right?
Because it lets you do that. They have firmware firmware for that lets that host act as a device and i think that the really one of
the things that is unfortunate about usb is the way this one single quote-unquote universal
specification has grown into all these disparate things means that there's lots of things that are almost bolted on.
And so having a dual-role device,
a device that can be both host or can be a device,
is a great idea.
It would have been really nice if we had something
that was kind of a plan for that from the beginning
or a better way of indicating those things.
So taking it by the USB specification, if you have a dual-role device,
it's not supposed to have a B connector on it.
It's not supposed to have a little micro USB B connector on it.
It's supposed to have a special connector called AB or micro AB.
And that is, it looks almost like a B connector and it's compatible,
but it's slightly different.
And in the end, because that's a relative, it's a different connector than people were using and it's compatible, but it's slightly different. And in the end, because
that's a relative, it's a different connector than people were using and it's relatively rare.
And often what winds up happening, the reason you get these on-the-go devices is not necessarily
because the manufacturer wants to develop an on-the-go device, but instead they took a
microcontroller or an application processor that has USB ports that can do either of the two.
And they just kind of brought it out to a micro B connector saying this is going to be a device.
And also we can do USB host. You kind of get these shoehorned in abilities instead of the
just the default ones. And I think the worst case you get a device that has a nice USB A socket
that's meant to be used as a host.
That can also be used as a device if you get an A-to-A cable.
Right, the A-to-A cable. It's like the definition of wrong.
It is the forbidden cable in almost all cases.
USB-C even took having that be the most wrong thing.
Or not USB-C, USB-3 made that be something that was no longer the the most wrong thing, or not USB-C, USB 3 made that be something that was no
longer the singular most wrong thing because they added a specification-less USB A to A cable
inside their debug spec. And so that is just the USB 3 lines. There's no USB 2 lines in that cable,
but it is an A to A cable that you can use to plug in from one of your computers to another
in order to do debugging from one computer to the other if both computers support the debug spec.
And all of these cables look exactly the same, don't they, for the C?
For C?
For C. I mean, I know what a micro-A is.
And the USB 3.0 ones are blue, at least, right?
They're supposed to be they're not
always yeah but the the c ones they all they all have the same connector they all have this they're
all they all just look the same so how am i supposed to know how many wires it has so they're
supposed to be labeled but to use the label that they specify the standard then the cable has to
be compliance tested because the logo is a trademark
of the USB promoters group
of the USB implementers forum.
And that means that
if you're just producing a cheap cable and you're not going
through that process, you're either just
sticking that logo on anyway,
or you're not labeling the cable at all.
I think some of my cables have like 10 on
them or SS for super speed
and a lightning bolt if they're Thunderbolt, something like that.
I mean, is those the kind of labels?
The kind of labels that you're supposed to have.
So you'll have a super speed 10, which is a super speed device that's good enough quality cable that can go up to 10 gigabits per second.
You'll have the ones that say 20, which lets you know that they can go twice that or like they can go uh twice that fast by having two sets of lines and then you have the five gigabit per
second ones that'll say five and then sometimes you'll see five times two which is a different
thing than 10 because it's two five so it's two five links on either side of the cable, right? As opposed to just one 10 link.
But the labeling just never winds up being applied exactly correctly.
So your best bet is either to buy a really nice cable tester.
Like I have one that is from a company called Lime Pulse.
I'm trying to check the actual thing on here.
I'm making a bunch of noise. But this cable tester is from a company called LimePulse.
I don't think they make this one anymore,
but there's a successor to it.
Essentially, it's a board with tons of LEDs on it
that you plug a cable into one USB-C connector
and plug it into the other,
and it just lights up a little LED
for every one of the connectors it's populated.
It's wonderful for doing anything with USB
because you know now that if something's not working,
it's definitely not the cable.
So that is, I think, the best way to be able to do this.
But if you don't have that, you kind of have to say,
this cable feels pretty thick.
It probably has all the connectors on there.
The USB standards body they they make money and it seems to be that they make money
mostly from the ids is that right so the the usb implementers forum is a big uh
there's a big group it's actually composed of a lot of people who make things with USB.
So theoretically, the major people in that group are people like Intel,
who are making money by having the specification there and building USB devices.
They do sell vendor ID and product IDs, but I think it's something like $5,000 to get your own whole vendor ID.
And for a company like Intel,
whatever portion of that that they'd be getting as a member of the USB Implementers Forum,
that's nothing to them.
So I think that's more the fee.
I think there is more to keep people from just claiming vendor IDs themselves, you know, and kind of keep it to the people who really want them.
But I think a lot of the way that they make money is by having USB devices and by being a member of the implementers forum, the USB implementers forum or the USB promoters group.
They can actually be the ones who are making the specification and must be the first people to have new USB devices
to market. Okay. But I wanted to ask about the IDs because there's this, do I need to register
an ID? I mean, it is really expensive. So it depends what you're doing with that ID.
If it's very just your machine and you're just doing this once, then you can get away with whatever.
Choose whatever ID you want.
The whole purpose of that ID is to just make sure that every device is universally recognizable by your operating system's drivers.
So if you pick a random number and it doesn't have a driver associated with it, and then you write your own driver and it's all on your own machine, then who cares?
Nobody's ever going to find out about that, and you don't have anything to complex with it, and then you write your own driver and it's all on your own machine, then who cares? Nobody's ever going to find out about that. And you don't have anything to
complex with it. And as long as your devices don't get out into the wild, you're not going
to cause any problems down the road. I mean, that's fine if I'm hacking on something,
but not so great if I'm making a product. Right. So if you're making a product, you have
a few options there that are so there's only one
option that the usb implementers forms the usb if says you're allowed to do which is pay the money
and get a vendor id the if you're willing to kind of ignore their word of law there are other things
you can do like if you're using a like a free scale chip sometimes you can write to free scale
and they'll give you a product ID under their vendor ID,
assuming you're going to buy a bunch of these chips.
So they'll give you just one.
And when you plug that device into Linux, for example,
it'll show up as a Freescale device with your product string on it,
but it's something you don't have to pay for.
Another option is if you're selling a product,
you can go and buy a single PID
from several people who have either acquired vendor IDs
and then try to sell them out.
And that, according to the USB Implementers Forum,
is very not legal.
But once they've given a vendor ID to someone,
they're kind of entering this contract that says,
this person gets to use all those vendor IDs.
And though we can take the vendor ID back from them,
we're also guaranteeing to everyone else who buys a vendor ID
that they're getting a unique one.
So they can't go and take that vendor ID that they've taken back
and give it to someone else.
So at that point, whether or not that person
still has the blessing of the USB implementers forum,
that's their vendor ID.
And the USB implementer forum is theoretically
never going to give it out again.
Because that would screw over whoever got it the next time.
There'd be other devices out there in the wild
that have product IDs from that vendor ID.
So you can buy product IDs from those kind of companies. And I
think there are people who sell them for like 10 or $20. And you just have to deal with the fact
that it looks a little bit bad to have your vendor ID say something like MCS, which is one of the
companies that are selling these things. And then the final option you have, if you're open source, is to go through a service like OpenMoCo or PID.codes.
And those are the vendor IDs from projects that were doing open source stuff
and then went under.
So their vendor IDs are still around,
and people who have kind of inherited those vendor IDs
then go and just give them out to open source projects.
So if you have to open source projects.
So if you have an open source thing you're just trying to give out like a library,
then you can go and get a product ID for that.
That actually seems really helpful
for people who are doing things that are open source
or things that are on Tindy sort of things.
That's very common to see used.
So I think the more common one right now is pid.codes,
which is a domain.
And then OpenMoco is I think the second most common.
Those will be in the show notes.
Okay.
So the USB IDs, those are kind of complicated.
We've talked about stacks, mostly tiny USB.
Do you have any other, and you mentioned a few other favorite stacks. Those are kind of complicated. We've talked about stacks, mostly tiny USB.
Do you have any other, and you mentioned a few other favorite stacks.
The stack that I'm currently working on, which I think is probably one of the neater stacks because it's hardware.
It's a hardware stack that you don't have to theoretically write any software to use
if you want to.
That's called Luna.
And I can send you a link to that in a bit but it's essentially github.com slash greatscottgadgets slash luna
and that is something where if you're doing an fpga design or you're doing like a processor
design where you're using an fpga or you have a couple of bucks to throw an fpga down next to
your processor that's something where you can implement a full USB device without ever having to, ideally, without really having to know much
about what you're doing. Like if you want something like a USB to UART converter, I have
pre-made gateway that works in lots of places that you can just kind of use. So it's one of my goals
in that is to take USB and make it really accessible by implementing a lot of this stuff for you especially if you're using an fpga
but also theoretically if you have something you can augment enough with an fpga or
eventually if you're kind of producing a whole if you're producing the microchip yourself
eventually people can start using that ip in their microchips. And that's all open source. It's all free to use.
So what does that look like as an implementer from the other side?
So I take Luna and I put it on my FPGA,
and my FPGA talks to maybe a microcontroller.
How do I speak to that?
What's the API like?
So I think the easiest way to do that
is actually using a, like a, you have two
options. You have like a FIFO style thing called a stream, which is you have, usually it's byte
sized. So you have eight parallel bytes, and then you have a signal that says whether you're,
whether the byte you're providing is valid. And then the FPGA gives you a signal back that says whether the byte you're providing is valid, and then the FPGA gives you a signal back
that says whether it accepted it
or whether you have to hold on.
So you have the ability to say,
take this byte from me,
and it has the ability to say,
okay, I've done that.
And as long as you kind of have
some shared clock,
that's really a fast way of getting data back and forth.
It's like that can be just taking the microcontroller's clock
and outputting it to the FPGA for that.
What does it look like on the other side?
I mean, it plugs into my computer.
What does my computer think it is?
Depends on how you have it set up,
but I actually have one of the pieces of gateway that makes it look like a UART that you're getting on the other side.
So it looks like one of those TTY ACM devices.
And so your software can just open up the COM port and get data at whatever speed your microcontroller is able to produce it up to that 48-ish reasonable kind of operating system limit what kind of
chip is on the Luna
board?
there's two kind of things in terms of
Luna. Luna is actually the library for
producing gateway as well as a board
that has kind of the reference
design. So if you were to get my
reference design for Luna that has
an ECP5 FPGA, which is an FPGA
from Lattice. It's like a $4 FPGA on there. But that library works on a variety of FPGAs,
including like the $1 and $2 FPGAs from Lattice and the ones that are less than a dollar in quantity.
So the chip that you use really depends.
Theoretically, one of the nice things about FPGAs is unlike a microcontroller,
it's a lot easier to reproduce the same design
in lots of different places
because what you have is a description of hardware,
and lots of different FPGAs can implement that same description.
So it's not like a microcontroller where I have ARM codes
and there's no way in hell I'm going to get that to run all my AVR, right?
There's kind of one general way that FPGAs are designed,
which is having this fabric that lets you build pieces of hardware.
And all the different tools are capable of taking the same descriptions
and producing those descriptions on top of that FPGA fabric.
Aren't FPGA tools very expensive?
It depends on what you consider an FPGA tool.
So most of the vendors have free FPGA tools for their lower-end FPGAs.
And then there's actually an open-source tool chain that's kind of like the equivalent of GCC, but for FPGAs. And then there's actually an open-source toolchain
that's kind of like the equivalent of GCC,
but for FPGAs that's entirely free.
What's it called?
The general case of that is either Symbaflow,
S-Y-M-B-I-F-L-O-W,
which is the one that calls itself the GCC of FPGAs.
And there's a toolchain called GOSYS and NextPNR,
which are hard to say,
but if you search for like OpenFPGA
or you search for GOSYS, Y-O-S-Y-S,
you'll find these.
And those SimbaFlow is targeting lots of different things,
including the modern Xilinx ones.
That's kind of a work in progress.
The others target the Lattice FPGAs.
So if you want to use a Lattice cheap FPGA,
those have really nice open tool chains that you can use
that don't require you to even install any proprietary software.
Those are really nice.
What do you use for Luna?
So Luna actually is, as a library, it doesn't care about which one of those things you build it on. No, no. What do you use for luna so the luna actually is as a library it doesn't care about which one of those
things you build it on no no what do you use for development uh what i use to develop the stuff i
mostly use an acp5 on the reference hardware so i usually use that gosis and next pnr chain
luna looking at the github it also says it's a us-tool. Well, that's a good thing. I meant to ask you about tools.
So Luna is designed to be...
Originally, I was actually creating...
I created the hardware first,
and the hardware was meant to be something you could do for...
I don't know if you have a USB analyzer.
Have you seen how much those things cost?
So much. So much that Alvaro
let me borrow his and I'm still grateful. So I think on my desk, I have the Beagle USB 3.1. I
think that one is only, it's only $5,000. And the fact that I say only is kind of lets you know the
price range for the super speed ones. I think the cheapest commercial one
that's really produced and supported is $300,
and that's for low speed and full speed.
The cheapest USB 2.0 one that's commercially supported,
I think it's like $1,000, something like that.
So they're really expensive devices.
And that makes it really, really hard
if you're someone who wants to learn about USB
to get your hands on that, right? Because because really i think you never are going to fully understand everything that's going on
until you have your ability to see things and your ability to kind of i need to play with things in
order to really feel like i have a good grasp on them and so one of the things i wanted to do with
a bunch of the things i've created is give you the ability to kind of reach out and touch USB
to be able to go and write little easy pieces of code that manipulate USB.
So that got me started on a project called Face Dancer,
which was originally started by two guys called Travis Goodspeed and Sergey Bretas.
They created this little prototype, and then I took that and built a library
and a bunch of hardware for it
that lets you essentially emulate USB devices in Python.
So you can mock up your own little USB device
in Python really quickly.
And then from there,
there's a thing called USB proxy that was added to that,
and that was written by Dominic Spill and myself.
And that is essentially something that lets you proxy USB data
from one machine to another and kind of manipulate the data
as it goes through there and makes it something that
you're not just like creating your own USB data,
but now seeing the data that flows
and giving yourself a chance to manipulate that.
And so that can be useful in some cases.
And then Luna was originally going to be this,
just this multi-tool that was the culmination of all of that.
It's a USB analyzer, it's something that lets you generate USB data,
lets you man in the middle of USB.
All those things are things I'm working on.
The analyzer works.
A lot of the rest of that stuff is kind of coming along.
But one of the things I did in building it was,
instead of going and buying something that had USB pre-done,
I took the FPGA, decided I was going to create something
that was as low-cost as possible.
And so I just bought three USB physical layer chips,
three USB PHYs, put them on this board,
and then decided I would implement the whole USB stack in hardware myself.
And that both makes it so there's an open-source hardware stack
that people can use and saves me a lot of money
on mass-producing these things.
So given that the ECP-5, the FPGAs that I use in there
are relatively inexpensive, that means if you wanted to build one of these from parts yourself,
the bill of materials cost, the BOM cost for that is like $20.
So I'm really hoping that that's going to let me actually get USB analyzers
that are cheap out to people.
And kind of the goal here is to have,
the best case scenario is that we get a mass production going and maybe some other people get mass productions of these kind of things going.
Because while it would be nice to produce these and sell them, I'm more concerned about having the tools be available to people.
And so people can do the, you know, the whole production at, like, half the cost that we can.
That's a win in my opinion because
then i can actually get tools to people so that was kind of the goal there is to have like a really
cheap uh usb analyzer that lets you also like poke the usb packets pretend you're a usb device
or pretend you're a usb host or create all these little synthetic usb kind of instruments. If I'm making a new device,
maybe doing high-speed data transfer
from a sensor system to a computer,
what do I need to know?
I mean, how do I get my head around the whole problem?
So that's the kind of thing where it really depends
on how well you need to
get things done. If you want to get one, if your sensor is something that is, you're trying to get
five megabytes, you know, or like five megabytes of data through the pipe, then that you have so
much overhead that you can use there that you don't have to worry about doing things right.
The, when you start getting to the point where you're getting toward the limits the specification that's when you have
to start thinking about uh how you want to do things and that requires you to be more of
and kind of aware of the things that usb offers usb offers four kinds of communication
and from the device's perspective they all look pretty much the same but the uh or to a degree
pretty close to the same but from the host's perspective these kind of modes all behave
differently so knowing how the host is going to want to interact with you is going to inform what
you do so those four modes are there's control, which is your I'm sending data
in the USB format. That's the standard way of doing little short data exchanges. You have bulk,
which is I want something that acts like a UART where I can just do things very quickly.
But I don't really care about latency. I don't have any real timing constraints.
You have interrupt, which is probably the worst name thing in USB because it's pulled. It's not
actually an interrupt.
It's the kind of thing that you would use to carry data that would be generated by an interrupt.
And so essentially what it does is a good USB host stack
is guaranteed to pull your device at a given rate.
So it's guaranteed to see this kind of interrupt-ish data
before too much time passes.
So then you have the interrupt stuff,
which is still guaranteed to deliver data,
but it is guaranteed to be polled at a fixed rate.
So that's for little status things
that you need to get to the host.
And then there's the final
and most complicated ones of these
is called isochronous,
which is a weird word,
but it's iso and chronos, which is same time. It's for any kind
of situation where you want to get data, the same amount of data through the USB line per individual
time slice. So if I want to get data at a very prescribed rate, and I don't necessarily care
about whether the data gets there in the sense of that there's nothing I can do if
the data doesn't get there, then that's kind of the case for isochronous. So if you think about
it, if I have a webcam, right, and I'm streaming something live on my webcam, I don't want to be
in a situation where if I drop a frame, I don't want the whole thing to go and say, hey, no,
send that frame back to me. I need to get that frame correctly before I move on to the next one, right? I just wanted to say,
okay, we didn't get this frame. Let's move on to the next correct frame. I want to constantly be
live. But that's the kind of case where you'd use isochronous. Isochronous is just, let me get data
through at a fixed rate, and I don't care if it gets there or not. It's kind of like UDP. So I
just want to send this data, and I hope it should get there, but if it doesn't or not right it's kind of like udp so i just want to send this data and i hope
you know it should get there but if it doesn't there's nothing i can do about it don't tell me
if you dropped it i don't care right so it gets to be the point where when you have that sensor
you have to now know is this sensor something where it's going to matter if i miss a sample
of this or i miss a set of samples or do i always want the latest ones and that's going to matter if I miss a sample of this or I miss a set of samples or do I always want the
latest ones and that's going to determine whether you want to use isochronous or not right and then
if you do care about the samples it's do I care about getting them in a very regular pattern or
is it okay for me to get a bunch of sample from the sensor in a burst, right? Or is it, you know, if I can get it in a burst
and I just want it to be fast, then I can use bulk.
If I need it to come through at a very predictable time interval,
like I need it to be pulled nicely, then I want to use interrupt.
And if I don't necessarily care if it comes through or not,
then I want to use isogranous.
So knowing essentially those four types
and knowing what you'd use them for
helps a lot in uh in choosing the uh the kind of method of transport you're going to use
and the lovely thing if you're developing a device if you're kind of a like a if you're
the embedded part of the system and you're just getting data from a sensor and sliding up to the
computer is that you don't they have to worry about a lot of the stuff that's involved in there.
When you say, I'm an interrupt, I'm actually extending interrupt data here, in USB terms,
I'm an interrupt endpoint, then you're hinting to the host that you want to be pulled at a certain
rate, and you just respond whenever the host asks you for data. You don't have to go and say,
I'm going to send this much data per unit time. You're telling the host to do the hard part for you. How does that,
I mean, I would have started with what communication class or what device class I
needed to be. How do those four modes work with the device classes I'm more familiar with, the CDC, the HID, and mass storage class?
So the real thing is if you have a requirement to not have your own driver, then you know you're going to be looking exclusively in those kinds of classes of devices.
If you don't have that requirement, if you can provide a driver on the host,
you have a lot more options,
and then you can create what's called a vendor-type device.
It's not a class.
It's not obeying any of those USB classes.
You just set your...
When it asks what your class is, you just say all...
It doesn't say all one.
It's 0xFF. I'm a vendor device.
I'm going to do whatever I want to,
and the driver on the other side will know what to do.
And so you don't have to follow one of those.
If you want to do something that's driverless, then not even a user-led driver, not even a program running.
Like if I'm doing a webcam sensor, like if it's actually my image sensor in a webcam and I want to send it up as though it were webcam data, then you start thinking, okay, this is something that I am going to,
I'm going to have this act as a USB video class device.
And then the choice of using isochronous is kind of made for you
because the specification for the USB video class there says to use isochronous endpoints.
Okay. Do you have any book suggestions? If my brain is starting to get full, where should I go to learn more?
So there's three kind of places I would suggest to look depending on how much you want to know.
One of them is if you're just trying to do, if you just want to think about things from completely a software side,
look at the documentation for libUSB
and look at what it has,
and then correlate that with,
there's a lovely little web,
like 10-page thing called USB in a Nutshell
by Beyond Logic.
It's essentially just a really short book on the internet,
and that is just really somewhere between a reference manual and an overview of USB.
And that'll get you some of how to think about things.
And if you kind of look at that as you're developing things, that'll help you understand.
If you want to understand USB from beginning to end and have an idea of everything before you jump into it.
There's a book series called USB Complete by Jan Axelson. And that is, there's one big book
called USB Complete. And then there's like USB embedded hosts complete and little subsections
like that that are kind of overlapping that core book.
And that is a good way to kind of have something physically in front of you
that you can read through to kind of understand USB stuff.
And then if you want to go full deep dive,
the specification is obtuse at points,
but it's actually fairly reasonable in others.
So if you want to understand how a computer can interface with USB,
you just want to read chapter nine computer can interface with USB, you just want
to read chapter nine, which is the USB device framework. And luckily the spec kind of does this
concentric thing where they have like, here's the high level concepts of USB, and then you can move
forward in the spec and it's like, here's how to implement those. So you can kind of read like,
I think chapter four is all the high-level communications types, and you can read through there and kind of get the architecture.
The specification actually is not something that's beyond reading to understand stuff.
But it's not concise in any way.
I mean, it's like 600 pages.
It's not the most verbose spec I've ever seen.
Keep in mind that a lot of the 600 pages are stuff you can just skip
like the if you don't care what materials make up a cable you can skip that section
and the like things that are in there include like a full technical drawing of the usb logo
say you know all the proportions of that and that stuff is not relevant to most people so kind of
knowing what you want to do
and selecting pieces of the spec from there really cuts down your reading like if you want to
like chapter nine i think it's like 20 pages i think each of the sections that are relevant to
things are like 20 pages in the core specification so it's not that bad at least for usb2
um that said if you you know if you look at USB in a nutshell,
that has those same 20 pages boiled down to one page.
So if you want that kind of thing,
I think those are kind of your good overviews.
If you're more interested in reading source code,
I think probably another way to learn this stuff that is maybe better is to go and play
with someone's existing USB code and try to figure out why they made the decisions they did based on
kind of a lightweight reference document like USB in a nutshell. Cool. Oh, I had one more question
that I meant to ask back when we were talking about various connectors and things. If somebody's
making a device now, let's say a product,
what connector should they be looking at?
Should everybody be implementing USB-C at this point,
or is it okay to still stick with the Mini-B and those older connectors?
So ideally, everyone will move to USB-C,
but the downside to that is that there is some complication in using USB-C, but the downside to that is that there is some complication in using USB-C, because
that reversible cable means that you have to be able to take the lines that are on the
top or the lines that are on the bottom of the cable and use those for your connections.
For USB-2, that's relatively easy, since the system's not going to completely explode if
you just connect the bottom and top of the connector together.
For USB 3, the speeds start getting to the point where you actually do have to do switching.
You have to buy USB-C multiplexer chips.
And if you want to start doing power delivery,
you want to be able to take more than just the very basic 5 volts,
then you start having to get a power delivery controller.
So if you want to skip all that and do uh like micro b i think we're still
in a point where micro b is accessible and so i think that having micro b things on products
it's still kind of an acceptable thing for at least for a little while but i think in the future
it's going to be all usbc in the future someday someday probably sooner than i want in the future, someday. Someday probably sooner than I want.
In the future when people start using it
and the prices of USB-B connectors start going up
because they're less common
and we're all kind of forced to move forward.
Before we close up the show,
I have an off-topic question.
I mean, it's off-topic for the show.
It's on-topic for the world at large right now.
You were ill recently.
Do you mind sharing a bit?
So actually in March, so I guess not that recently,
even though it feels like time has stopped lately,
I did have something that was presumptively COVID
and that I had a lot of difficulty breathing
and had my pulse oximeter readings were way down in that kind of danger level.
We were not doing testing at the time, so I don't have a definitive answer as to whether that was.
But I'd be very surprised if it wasn't because I had kind of all the classic symptoms.
And that wasn't fun. I will say that the one blessing about it, the one like positive of it, was that it actually didn't come with like a terrible head kind of head cloud that comes with a lot of diseases.
It's like if you get the flu, sometimes you just will not be able to think about things for, you know, three or four days straight. covid symptoms i had uh let me sit there with the computer and as long as i didn't get up or move i
could still kind of do things so instead of sitting there and just like doing nothing i could actually
like write usb code if i wanted to i wasn't asleep and that i think helped me go you know
not be stir crazy during the whole thing but you mentioned something about hedgehogs
yeah it didn't fail i would describe the feeling of that as having a hedgehog move into your lungs
um and that's not altogether a pleasant sensation and it's not like it as adorable as hedgehogs are
but also it kind of for a lot of people you do actually wind up having symptoms afterwards that kind of feel like once the hedgehog has moved out,
there's still the points where you were poked.
So it's not really a fun thing.
And so if you can avoid it by staying inside and doing some embedded project,
then by all means do that instead of the social events
that I'm sure everyone're gonna everyone had planned
up until this point especially they don't go to conferences or do hacker cons don't start those
again too early because the it was very touch and go and like early march whether some of these
events were going to happen and then we all kind of came to the conclusion of canceling them or
going virtual and i just hope we don't start those things up too
soon because it doesn't seem like a responsible thing for us to do in our communities.
Well, Kate, thank you for talking about that. And thank you for being with us. Do you have
any thoughts you'd like to leave us with? Yeah, I would just tell everyone who's doing
this kind of low-level hardware stuff that I would just love it if everyone could focus on
being welcoming. Because one of the things I see a lot in our community is either people who get really
obsessed with a single kind of way of doing things or think that their way is the right way
and they're not super permissive of people who want to come and join the community and I just
think if we could all really open our arms to people, whether they're doing CircuitPython or Arduino or doing really low-level C or bringing C++ or Rust or any kind of unexpected language to a microcontroller,
if we could all just kind of think about things from the perspective of, I want this person to be a peer and a programmer or an engineer with me, rather than thinking about, oh, I want this person to be good enough to be a, you know, a peer and a programmer or, you know, an engineer with me, rather than
thinking about, oh, I want this person to be good enough to be an engineer. I think that would make
things a lot better for everyone. Yeah. Totally agree. Our guest has been Kate Temkin,
hardware hacker and low-level engineer, leader of software at Great Scott Gadgets.
Thanks, Kate.
Thank you.
Thank you to Christopher for producing and co-hosting.
Thank you to our Patreon listener Slack group for questions.
And thank you for listening.
You can always contact us at show at embedded.fm
or hit the contact link on Embedded FM.
And I have a quote to leave you with.
This by Madeline L'Engle.
A book, too, can be a star, a living fire to lighten the darkness leading out into the expanding universe.
Embedded is an independently produced radio show that focuses on the many aspects of engineering.
It is a production of Logical Elegance, an embedded software consulting company in California.
If there are advertisements in the show, we did not put them there and do not receive money from them.
At this time, our sponsors are Logical Elegance and listeners like you.