Skip to content
Snippets Groups Projects
Commit a0463b6c authored by Erik Strand's avatar Erik Strand
Browse files

Update networking page

parent 3be21c8f
Branches
No related tags found
No related merge requests found
...@@ -5,19 +5,18 @@ menu = "main" ...@@ -5,19 +5,18 @@ menu = "main"
weight = 15 weight = 15
+++ +++
Files: [audio_interface.sch](/designs/14_audio_interface.sch) [audio_interface.brd](/designs/14_audio_interface.brd) Files: [audio_interface.sch](/designs/14_audio_interface.sch) [audio_interface.brd](/designs/14_audio_interface.brd) [audio_interface_2.sch](/designs/14_audio_interface_2.sch) [audio_interface.brd_2](/designs/14_audio_interface_2.brd) [serial_cpp](https://gitlab.cba.mit.edu/erik/serial_cpp) [lufa](https://gitlab.cba.mit.edu/erik/lufa) (see Demos/Devices/ClassDriver/VirtualSerial)
This week we're making machines talk to each other. I've used I2C before, so I'm curious to venture into the wonderful world of USB.
This week we're making machines talk to each other. I've used I2C before, so want to venture into using USB to connect my own boards with computers.
## Board Design ## Board Design
For part of my final project I want to make my own USB audio recording device. So I'll try to develop all the necessary electronics this week. I have all the analog circuitry I need from [inputs week](../10_input_devices). But I don't have a board ready to go with a USB-capable microcontroller (bit-banging will not suffice, since I need the CPU to be available for audio processing). I've heard that [LUFA](http://www.fourwalledcubicle.com/LUFA.php) is much nicer than ATMEL's own USB [libraries](https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591207) so I'll try to use that. I'd like to use an XMEGA board, since they are fast, have a good amount of memory for audio applications, and I've used them [recently](../12_machine_week). LUFA's [XMEGA support](http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/_page__x_m_e_g_a_support.html) is technically experimental, but people have been using it since [2013](https://www.avrfreaks.net/forum/lufa-xmega-hello-world). So I think it should be ok. For part of my final project I want to make my own USB audio recording device. So I'll try to develop all the necessary electronics this week. I have the analog circuitry I need from [inputs week](../10_input_devices). But I don't have a board ready to go with a USB-capable microcontroller (bit-banging will not suffice, since I need the CPU to be available for audio processing). I've heard that [LUFA](http://www.fourwalledcubicle.com/LUFA.php) is much nicer than ATMEL's own USB [libraries](https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591207) so I'll try to use that. I'd like to use an XMEGA board, since they are fast, have a good amount of memory for audio applications, and I've used them [recently](../12_machine_week). LUFA's [XMEGA support](http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/_page__x_m_e_g_a_support.html) is technically experimental, but people have been using it since [2013](https://www.avrfreaks.net/forum/lufa-xmega-hello-world). So I think it should be ok.
![](/img/14_schematic.png) ![](/img/14_schematic.png)
On the left I have my microcontroller. I'm using an external 16MHz crystal to give it an accurate clock signal. High speed USB 2.0 requires a 48Mhz clock, which I can get by multiplying the crystal's output by 3 using the XMEGA's phase locked loop (PLL). On top I have my power section, including a regulator to bump USB's 5V power down to 3.3V, some filtering capacitors, and a power indicator LED. The two circuit groups with op-amps together amplify and bias the audio input, as I learned in [inputs week](../10_input_devices). Finally I have some headers that provide convenient debugging access to certain signals, and a 0-ohm resistor I needed to connect all my ground signals. On the left I have my microcontroller. I'm using an external 16MHz crystal to give it an accurate clock signal. High speed USB 2.0 requires a 48MHz clock, which I can get by multiplying the crystal's output by 3 using the XMEGA's phase locked loop (PLL). On top I have my power section, including a regulator to bump USB's 5V power down to 3.3V, some filtering capacitors, and a power indicator LED. The two circuit groups with op-amps together amplify and bias the audio input, as I learned in [inputs week](../10_input_devices). Finally I have some headers that provide convenient debugging access to certain signals, and a 0-ohm resistor I needed to connect all my ground signals.
![](/img/14_board.png) ![](/img/14_board.png)
...@@ -30,7 +29,7 @@ I milled the board on a Roland SRM-20. For the most part the smaller traces work ...@@ -30,7 +29,7 @@ I milled the board on a Roland SRM-20. For the most part the smaller traces work
![](/img/14_milled.jpg) ![](/img/14_milled.jpg)
I soldered the XMEGA and the USB connector first, since I knew jumping the USB power wire and dealing with the tiny XMEGA traces would be the trickiest tasks. The XMEGA's leads are smaller than anything I'd soldered before, but it still went fine. Most of them I soldered individually, but in a few places I globed pins together and later removed the excess solder to unshort them. Generous amounts of flux were essential, since I used a very fine guage of solder that doesn't have a flux core. To connect the USB power, I took a small piece of wire and used it to jump directly from the USB conenctor pin to the trace. It was so short that it was almost impossible to solder one side without melting the other, but eventually I got it to stick in place with good quality joints on either side. (In the photo below it looks like it's shorted to the USB plug chassis, but this isn't the case.) After these I soldered on the minimal number of other components to get the power indicator LED working (ok, the crystal wasn't necessary but I had already taken it out). I soldered the XMEGA and the USB connector first, since I knew jumping the USB power wire and dealing with the tiny XMEGA traces would be the trickiest tasks. The XMEGA's leads are smaller than anything I'd soldered before, but it still went fine. Most of them I soldered individually, but in a few places I globed pins together and later removed the excess solder to unshort them. Generous amounts of flux were essential, since I used a very fine gauge of solder that doesn't have a flux core. To connect the USB power, I took a small piece of wire and used it to jump directly from the USB connector pin to the trace. It was so short that it was almost impossible to solder one side without melting (and thus destabilizing) the other, but eventually I got it to stick in place with good quality joints on both sides. (In the photo below it looks like it's shorted to the USB plug chassis, but the jumper wire is safely above the leftmost lead.) After these I soldered on the minimal number of other components to get the power indicator LED working (ok, the crystal wasn't necessary but I had already taken it out).
![](/img/14_powered_on.jpg) ![](/img/14_powered_on.jpg)
...@@ -39,9 +38,69 @@ From here it was a routine soldering job. ...@@ -39,9 +38,69 @@ From here it was a routine soldering job.
![](/img/14_stuffed.jpg) ![](/img/14_stuffed.jpg)
## Software ## Software (First Attempt)
I started by flashing it with an empty hello world program, to verify that it could be programmed at all. Then I started writing the USB software. Unfortunately, disaster struck: I accidentally tore off the USB connector. I'm in the process of fixing this now. I started by flashing it with an empty hello world program, to verify that it could be programmed at all. Then I cloned LUFA and started trying to adapt an example to work for my board. Unfortunately, disaster struck: I accidentally tore off the USB connector. I knew this was a risk, since I had waited to solder on the
![](/img/14_broken_connector.jpg) ![](/img/14_broken_connector.jpg)
I figured it was worth a shot at repairing.
![](/img/14_almost_repaired.jpg)
I think I got most of the leads reconnected, though in the image above the power jumper has some really ugly (and maybe cold) joints. Eventually I decided I should save myself the frustration of working with a damaged board. Especially since I learned of a few things I could have done better.
## Back to the Drawing Board
Or back to board drawing, as it were. Anyway, I wanted to make a few changes before milling again:
- Add additional bypass capacitors near all the XMEGA's power pins
- Get rid of the 22 ohm resistors (unlike the ATmegas, the ATxmegas have these internally)
- Switch to a single-ended op-amp configuration
- Add mounting holes and pads for an external audio jack and volume knob
The first is just good practice for microcontrollers. I added 0.1uF caps near all the XMEGA's power pins, and a few 10uF caps near potentially large current sinks (i.e. LEDs and op-amps). I had added the 22ohm resistors because all the [examples](../../../../../863.17/CBA/people/tomasero/index.html) I [looked at](../../../../../863.14/CBA/people/andrew_mao/week11) had them. But after going through the XMEGA's datasheet in more detail, I found that it has an "integrated on-chip USB transceiver, no external components needed". I wanted to go to a single-ended op-amp configuration to make it simpler to add a potentiometer to control gain. With my current differential setup, I would have to use a double-ganged pot, and if the two resistances didn't stay exactly the same at all times there'd be additional error in my output. So I'll just connect one side of the input to ground, and send the other through an AC-coupled non-inverting amplifier with a DC bias. Finally, the gain control knob and audio jack will be better off mounted to the chassis of the device rather than the board, so that the board doesn't bear any unnecessary mechanical load. It would be nice to attach the USB jack to the chassis as well, but the USB jacks we have in stock are surface mount, and since it's good to keep the data leads as short as possible, I'll leave it on the board.
![](/img/14_schematic_v2.png)
![](/img/14_board_v2.jpg)
If I lay this out a third time, I'll make more careful use of the grid. I could also move the LEDS to the left of the XMEGA, and connect the audio signal to a pin on its bottom side, to shorten my critical analog traces. Speaking of which, I could have a separate analog ground plane and voltage rail. But this will definitely work for now.
## More Milling
I hoped that the ripped leads on my first board were a fluke, so I milled the second one just like the first. But the same thing happened, in the exact same place.
![](/img/14_ripped_traces_again.jpg)
Rather than deal with jumpers again, I thought I'd fix the manufacturing. So I grabbed a 0.01" endmill to use just for the USB pads.
![](/img/14_good_traces.jpg)
![](/img/14_stuffed_v2.jpg)
## Software (Second Attempt)
To begin I'd like to make my board become a USB virtual serial device, since this is probably the simplest example that LUFA has, and I already have my own C++ to listen to serial devices. (Side note: I wasn't sure my code would work with USB virtual serial devices, but Linux presents these devices as device files in `/dev` just like the FTDI device I used before. So though different drivers are being invoked under the hood, at the level of `libserialport` they look the same.)
Though the LUFA code looked quite daunting at first, I only needed to change a few things to get it to run on my board. First, I commented out everything referencing code from `LEDS.h` and `Joystick.h`, since I don't want to create these files for my board (and I don't even have a joystick). Instead of reading a value from a joystick, I'll just spam "hello world" all the time. In the Makefile, I set `ARCH` to `XMEGA`, and the clock rate to 48MHz.
After programming, my serial port code detects a new device: `/dev/ttyACM0`. When I open the port, I get see a constant stream of "hello world" as expected.
![](/img/14_hello_world_usb.png)
Since this week is ultimately about networks with addresses, let's try to find the address that my board is assigned by my computer. I grepped for "address" in LUFA and after following a few function calls found my way to `LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h`. At line 217 LUFA is writing the newly assigned address to one of the XMEGA's registers.
{{< highlight c >}}
static inline void USB_Device_EnableDeviceAddress(const uint8_t Address)
{
USB.ADDR = Address;
}
{{< /highlight >}}
Instead of spamming hello world, I can read back this register and make my board output its own address.
![](/img/14_usb_address.png)
This diff is collapsed.
This diff is collapsed.
static/img/14_almost_repaired.jpg

113 KiB

static/img/14_board_v2.jpg

119 KiB

static/img/14_good_traces.jpg

104 KiB

static/img/14_hello_world_usb.png

10.3 KiB

static/img/14_ripped_traces_again.jpg

98.5 KiB

static/img/14_schematic_v2.png

158 KiB

static/img/14_stuffed_v2.jpg

124 KiB

static/img/14_usb_address.png

2.74 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment