Fixing a busy CP210x serial device on Ubuntu

April 5, 2020

I had the opportunity to reorganize my local machines. As part of that, I wanted to plug my firewall’s serial port into USB serial and pop that into my server. I have a CP2104 serial device that I bought with my PC Engines apu2 which I use for a firewall.

The USB serial device worked fine when plugged into my Windows 8 laptop, but I want my server to be able to connect to my firewall even when the network is down. Because the apu2 is headless, it’s nice to have something that’s plugged into a monitor when I need to fix things.

I plugged the USB serial port in, and tried to connect to my firewall with minicom. I got this instead:

$ minicom 
minicom: cannot open /dev/ttyUSB0: Device or resource busy

So, time to look at who has /dev/ttyUSB0 open:

$ sudo lsof | grep ttyUSB0
gpsd 416 root 3u CHR 188,0 0t0 176 /dev/ttyUSB0

Ok, why is gpsd holding /dev/ttyUSB0 open? It’s true I have a GPS attached to my server, but that runs as /dev/ttyACM0 and has nothing to do with /dev/ttyUSB0. Hmm… time to search and find this in the gpsd FAQ: Why does GPSD open non-GPS USB devices?

That made me suspicious. See, gpsd is trying to be too friendly – and to do that, it opens a whole bunch of possibly GPS devices even if they’re not GPS devices! Could that be my problem?

$ lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 008 Device 003: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x UART Bridge / myAVR mySmartUSB light
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 040: ID 1546:01a7 U-Blox AG 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Hmm… let’s take a peek in /lib/udev/rules.d/60-gpsd.rules:

... blah blah blah...
# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) [linux module: cp210x]
ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"
... more blah...

So in an effort to detect the Holux m241 and Wintec grays2 wbt-201, it’s matching the vendor and product ID of my CP2104 serial device as well! Luckily, I don’t have any of those GPS devices, so a quick snip:

# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) [linux module: cp210x]
# commented out because it interferes with Andrew's PC Engines 2104 USB serial cable
#ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"

was all it took. Now my USB serial device shows up as a serial device, and is not held open by a GPS daemon.

I have to disagree with the GPSD FAQ’s statement, “It’s not a problem we can solve with clever programming, the devices simply don’t yield enough information about themselves to avoid conflicts.” Err, no… clever programming would have the user run through an install procedure which involved plugging the device in, and detecting the device. Then they could update the udev rules so that only the device that a user owned was stolen by gpsd, and not all serial devices on the planet that happened to match a vendor/product ID that they knew about.

Adding ATtiny support to Arduino IDE 1.6.1

March 22, 2015

I recently upgrade from the 1.0.5 version of the Arduino IDE to 1.6.1. Things aren’t completely smooth – in particular, I was using Coding Badly’s cores for ATtiny85, ATtiny84 and ATtiny2313.

Unfortunately, those haven’t yet been updated for the new layout specified in the 1.6.x IDE. So instead I switched for now at least to the damellis cores (which support ATtiny85 and ATtiny84, but not ATtiny2313/4313).

Installing this is a matter of unzipping it in the sketchbook/hardware folder (on my Windows box in C:\Users\{my user}\Documents\Arduino).

In Windows cmd shell:
cd "C:\Users\{my user}\Documents\Arduino"
mkdir hardware
unzip c:\{whatever}\
cd hardware
move ..\attiny-ide-1.6.x\attiny .
cd ..
rmdir attiny-ide-1.6.x

At some point in the future either the Coding Badly cores will support IDE 1.6 (hopefully with the nice variants structure that the damellis cores use) or the damellis cores will do ATtinyX313s.

Trying to resurrect a dead Linksys WRT54GS router

September 1, 2014

I recently went through heroic efforts to bring a dead Linksys WRT54GS router back to life. These routers are great for Broadband Hamnet so I really wanted to get it working, but no dice.

But I don’t want to forget what I did, so I’m documenting it here.

Fix the hardware

The first problem was that the router made a strange buzzing sound. I opened the router and discovered that LX2 in particular, but also LX1 (two chokes at the power supply input) were actually vibrating when I put my finger on them. In addition, the capacitors near it were hot to the touch.

This was described in this post as an electrolytic capacitor problem. Sure enough, when I replaced CX2 with a new 220 uF 25 V electrolytic capacitor, the device settled down. At this point, the power LED was flashing (a bad sign) but at least it was now flashing at a regular speed. While I was soldering, I took the time to add a 12-pin header to the router’s JTAG port.

Reflash the Firmware

Following the unbrick article here, I wasn’t able to ping the router. No matter what, I’d get “destination host unreachable” – even though my IP was the same as the router, ostensibly. So I figured flashing was required.

I started out by trying to get a SEGGER J-Link talking to the JTAG port. I used the pinouts for the WRT54G described here for the WRT54GS, and the pinouts for the J-Link described here. Note that RESET on the J-Link is nSRST on the WRT54GS.

After I’d done that, I wasn’t able to get the J-Link talking. It looks as if the J-Link software wants to talk only to devices it knows about – or at least, that’s all I could figure out about it. Trying to set it to MIPS mode to impersonate EJTAG didn’t yield any success either.

So it was time for a different option. I didn’t have a parallel port handy, but I did have a Raspberry Pi. And a wonderful individual has taken the time to port tjtag to the Raspberry Pi. I cloned the Git repo to my Pi and built it. I had to use:

git clone git://

to grab the Git repo, since https wants an auth key and I don’t have one. After that I followed the Setup instructions and got tjtag built.

I connected things up as described in the wiring diagram, and had success! I was able to probe the router. (I had to run sudo ./tjtag -probeonly instead of just ./tjtag.)

Then I went off to the tjtag instructions here. The first few times I did:

sudo ./tjtag -backup:cfe

I got different results. It appears that tjtag on the Pi spends so much time sending output to the console that it messes up its timing. So I redirected the output to /dev/null, and after that I got consistent backups.

Once I had an nvram backup, I tried erasing the nvram:

sudo ./tjtag -erase:nvram

This worked, but didn’t solve my problem. So I thought I might have had a corrupted CFE. I located the CFE for my router here and modified it to have my IP addresses using imgtool_nvram. I used the following command:

imgtool_nvram.exe wrt54gs1.0-CFE.
BIN et0macaddr=00:11:22:33:44:55 il0macaddr=00:11:22:33:44:56

(substituting my real MAC address and one higher than it.) Then I dumped that back on the Pi as CFE.BIN, and did:

sudo ./tjtag -flash:cfe > /tmp/out

That worked, but still no joy in Mudville after I did the flash. No matter what, when I pinged I got destination unreachable. I wondered if it was Windows messing with me, so I booted to Kali to see what happened there. Still no dice.

Finally, I thought it might be a bad kernel, so I nuked it:

sudo ./tjtag -erase:kernel

Even with that, the router’s still not responding. Other than re-reflashing the CFE on the assumption that the bad kernel corrupted it, I’m out of ideas.

Drat, I thought I had it when I saw the instructions about setting the address with arp. (arp -s aa-bb-cc-dd-ee-ff if you’re on Windows.) But even when I did that (using the MAC address that I flashed), I still had nothing. I even stuffed Wireshark on the end to listen for any packets. He’s dead, Jim.


Hacking the APC Smart-UPS 1000

May 18, 2014

I have an old APC Smart-UPS 1000 (SU1000NET) that recently started giving me bad battery warning beeps. I’ve had that in the past, and replacing the battery has always solved it. This time it didn’t.

First I read that sometimes the battery constant for these UPS devices can get confused. (I read that at: So I did the reset procedure described there.

A few things to keep in mind before you do this:

  • You need an APC cable, not a plain serial cable. In my case I had one that I hooked up to an FTDI USB serial cable.
  • The instructions from the site above aren’t exact – they make reference to pressing **1** but they really mean press 1
  • There is no need to type any keys other than the ones specified. No returns, etc.
  • The keys are case-sensitive. Y is not y.

So I hooked the cable up, connected a terminal at 2400/8/N/1 Xon and changed the value of the battery constant from 79 back up to A0, which I’d read was the correct value for the SU1000NET. Here are the keys I entered:

(you see SM)
1 (then wait 1 second) 1
(you see PROG)
(I saw 79)
+++++++ (and kept on pressing + slowly until I saw A0)
(you see BYE)

I pressed Y0R to see that it had been properly set. Then I pressed the self-test button and… more beeps and another battery failure indication. Boo.

So I figure something has gone awry with this UPS. I wanted to shut off the beeps at least. That led me to this wonderful site:

That describes the entire PowerChute protocol. So I decided to turn off the weekly self-test. I did:
Y (see SM)
E (see 336)
+ (see OK)
E (see 168)
+ (see OK)
E (see ON)
+ (see OK)
E (see OFF)
R (see BYE)

Hopefully that will turn the annoying beeps at 3am off. In the meantime, my UPS still tells me that the new batteries are bad. But when it loses power, it still does the right thing… so hopefully this will work.

Using the TinyLoadr to program ATtiny84s

November 27, 2013

I’ve been using the excellent TinyLoadr Shield to program a bunch of ATtiny2313 chips I’ve got. Doing so was easy.

But when I moved over to program ATtiny84s, I ran into a bunch of problems. First, I’d get an error when burning the bootloader:

configuration file for part ATtiny84
avrdude: Yikes!  Invalid device signature.

This was because, although I’d switched all the switches on in the second bank (and off in the first and third banks), I’d neglected to move the three jumpers below them from ATtinyx313 to Other.

Once I did that, I started getting different errors:

avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
avrdude: stk500_cmd(): protocol error


avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
avrdude: stk500_cmd(): programmer is out of sync

This is due to a defect in Arduino 1.0. Luckily, more information about the problem is here:

The upshot: I went into
c:\Program Files\Arduino\hardware\arduino\cores\arduino
and edited HardwareSerial.cpp to have the following:

#if (RAMEND < 1000)
// Was 64; changed to 128 for serial buffer overflow problem
  #define SERIAL_BUFFER_SIZE 128

I then reburned ArduinoISP on my Uno, then plugged the TinyLoadr back in. After that, I was able to burn ATtiny84s with no problem.

Repairing a Samsung LN32A450

December 12, 2012

I own a Samsung LN32A450 TV set, which has been fairly good so far… until last weekend, when it didn’t turn on. Instead, the power LED flashed steadily at about one flash every 500 ms.

It seems that my TV set suffered from the capacitor plague. A bunch of the Samwha capacitors swelled up and were no longer to spec. I could order a replacement board (the board is BN44-00214A available from A little searching showed that others had successfully revived their power boards just by replacing the capacitors.

First, I had to open the TV set. This involved removing 16 screws (all the same size) from the back. I discoverd I had to be careful with the ones marked “S” – those four also hold the TV stand in place, so I wanted to remove them last. Also, there’s a screw on the back panel below the “EX-Link” connector, and another one on the back underneath the A/V 2 inputs.

Once I did that I could slide the back off (face down, since the support was unscrewed). The power board is the one in the middle. There are five connectors to disconnect from there: two at the upper left, one at the upper right, and two power connectors that go to the lower right. In my case they stayed in the right position once I removed them because there was tape holding them to the flat panel.

After that, I removed 6 small screws that held the power board in. I didn’t need to remove any of the standoffs – they’re just there to push the board away from the flat panel.

When I investigated the board, I could see the telltale swelling of capacitors that indicated problems. I saw problems with four capacitors:

CB852 in the middle right of the board: 2200 uF 10V
CW856 near the top left: 470 uF 25V
CW858 right below CW856: 680 uF 25V
CM868 right below CW858: 680 uF 35V

Some people reported success with using Radio Shack replacement capacitors. I was a little nervous about that – these caps are all rated to 105 degrees C and have high ripple current tolerance, and I didn’t want to swap in something I’d just have to replace later. I ended up getting replacements from Digi-Key. They have a minimum $25 order (otherwise they charge you $5 for handling). Luckily I had some other stuff to buy at the same time.

I replaced them with the following:

CB852: Panasonic EEU-FC1A222L (Digi-Key part P11189-ND)
CW856: Panasonic EEU-FM1E471 (Digi-Key part P12388-ND)
CW858: Panasonic EEU-FM1E681 (Digi-Key part P12390-ND)
CM868: Panasonic EEU-FM1V681 (Digi-Key part P12417-ND)

The replacement for CB852 was about 1 cm taller than the original part, and that made it the tallest part on the board. I was a little worried about that, but there seemed to be enough clearance that it didn’t cause a problem.

These capacitors are electrolytic and have a polarity, so I had to replace them the same way ’round that the originals were. Luckily, on my circuit board all the negative terminals were marked with a white semicircle underneath the capacitor.

After that, I plugged the cables back into the board (not forgetting the single-pin green ground cable). Then I put the 6 screws back.

Next I put the cover back on and put the 16 screws back in. I started with the base “S” screws, then the top three, then kind of haphazardly put the rest in the right places.

Then I powered up. Success! The TV came on and was as good as it was before this happened.

A few links I found useful:

Maxtor Shared Storage II 320 G power supply

December 9, 2012

Since I have recently moved, I’ve discovered how much I hate devices that don’t clearly label their power supplies. All my wall warts got detached from their devices in the move, and I’m gradually re-unifying them.

Today’s example: the Maxtor Shared Storage II 320 G external drive. It takes 12 volts DC, 3A, centre positive, and a brick I had from Goodwill with a 5.5mm outer barrel connector seemed to fit well.

Repairing a Dell Inspiron N4010

December 1, 2012

I recently had a friend bring me a Dell Inspiron N4010. The laptop wouldn’t boot up, and the friend wanted to get the data off the hard drive.

I figured that would be a fairly easy task. Little did I know…. I started by looking at Youtube videos about taking apart the N4010. Here’s the best Inspiron N4010 video – or rather, first in a series of three for over 30 minutes total time.

Turns out, Dell in their infinite wisdom decided not to put a door on the case to allow access to the hard drive. Instead, you have to remove the keyboard and motherboard to swap it out. This proves that Dell’s engineering department is willing to hire the insane.

Luckily, the video showed disassembly as well as assembly. I knew my friend had taken the laptop to Best Buy a few weeks before it stopped working to put a new hard drive in. (And again after it stopped: that time the Geek Squad claimed “no fix was possible” because there were no BIOS beeps.) The video showed a stick-on plastic piece that wasn’t present (any more) on my friend’s laptop between the keyboard and the motherboard.

With the laptop disassembled, I said “why not” and tried to boot. It came up. I connected the laptop up to the network and backed up the hard drive.

The stick-on plastic piece appeared to keep the keyboard from shorting the motherboard. More of that Dell quality. I’m guessing the Geek Squad just tossed it. I fabricated a quick replacement from some polyester film I had hanging around. Who knows if it will last, but at least the machine boots now.

I’m really glad I did this. It made me 100% sure I would never buy a Dell laptop. Ever.

Final cleanup for the ALIX firewall

July 6, 2012

Finally, there are a few things that I either forgot to do or that make life easier.

Setting up localtime
By defaut, /etc/localtime is set to Alberta, where OpenBSD has its home. I need to set it to somewhere closer.

rm /etc/localtime; ln -s /usr/share/zoneinfo/US/Mountain /etc/localtime

Now date shows the correct time.

I wrote a script to make the LEDs move back and forth. I start this at boot. (In an earlier version of the firewall, I edited /etc/rc to turn LEDs on when certain thresholds had been passed in the boot process. But now I don’t want to muck up /etc/rc so much.)

First of all, you need to allow the ports to be written before OpenBSD gets all secure on you. Edit /etc/rc.securelevel and add:

# Place local actions here.
echo -n 'enabling LED pins'
gpioctl -q /dev/gpio0 6 set out iout
gpioctl -q /dev/gpio0 25 set out iout
gpioctl -q /dev/gpio0 27 set out iout

I got these numbers from the Status LEDs section of the ALIX manual.

Then create /usr/local/bin/cylon:

#!/bin/ksh -

gpioctl -q /dev/gpio0 6 0
gpioctl -q /dev/gpio0 25 0
gpioctl -q /dev/gpio0 27 1

gpioctl -q /dev/gpio0 6 0
gpioctl -q /dev/gpio0 25 1
gpioctl -q /dev/gpio0 27 0

gpioctl -q /dev/gpio0 6 1
gpioctl -q /dev/gpio0 25 0
gpioctl -q /dev/gpio0 27 0

gpioctl -q /dev/gpio0 6 0
gpioctl -q /dev/gpio0 25 0
gpioctl -q /dev/gpio0 27 0

while [ true ] ; do
 sleep 1
 sleep 1
 sleep 1
 sleep 1

Finally, start it from /etc/rc.local:

# Add your local startup actions here.
echo -n 'cylon'
sh /usr/local/bin/cylon &

On reboot, yay, blinky! That at least tells you the kernel hasn’t crashed.

Reducing the mail
Because flashrd is really OpenBSD, it sends mail more suited to a server than a firewall with limited disk.

First thing I noticed:

Running security(8):

Checking special files and directories.
Output format is:
                criteria (shouldbe, reallyis)
        permissions (0644, 0755)

I fixed that with a chmod 0644 /etc/rc.conf.local. So now /usr/libexec/security shows no problems. Good.

Once that’s done, make things complain less:

crontab -uroot -e

and comment out:

#30     1       *       *       *       /bin/sh /etc/daily
#30     3       *       *       6       /bin/sh /etc/weekly

This prevents the daily and weekly reports, leaving just the monthly one.

Next, I noticed that sendmail gets run from root’s crontab, so it doesn’t need to run at boot:


sendmail_flags=NO       # "-L sm-mta -C/etc/mail/ -bd -q30m"

That should keep the thing running a little longer without running out of disk. Actually, /var/mail is on the MFS, so it will keep it from running out of ramdisk.

(This post is part of Building an ALIX firewall)

Building a quiet MythTV box – selecting a case

April 20, 2012

I’ve started looking around for a quiet but thermally good case for a MythTV box. My first thought was to do an HTPC case – the Lian Li HTPC C60 looked good.

But then I started worrying about airflow around the case. I’ve got a fairly narrow spot to put it in – about 46 cm – so a PC that’s 44 cm wide doesn’t leave a lot of room for cooling.

I decided to look into mini towers instead. The Lian Li V600F looks like it would be nice, but it has these ugly blue fans.

I also looked into the NZXT H2 (some were saying it was too flimsy), Antec P183 (too tall, not a mini tower) and Silverstone TJ-8e (an 18 inch fan in front, but only that. How hard to get a replacement when it dies?)

Now I’m leaning towards the Lian Li B10. It’s too bad that SPCR hasn’t reviewed it – they seem to know a thing or two about quiet and heat.