This afternoon we took my son to a soft play area close to our house. He's around 18 months now, and going through a bit of a sleep regression, so we though it would be good to tire him out so that he gets a good night's rest[1].
He quickly got bored of the toddler play area, which consisted of a ball pit, a couple of crawling areas and a small slide. I decided to take him to where the big kids play, where he can go as long as he is accompanied by an adult the whole time. This specific play area is known for their big slides.
There are some really scary slides, even for an adult, where there is an almost vertical drop for a couple of meters before it evens out. Obviously I couldn't take him down those ones, but there were a few open and closed slides where he could sit on my lap and we go down together. And boy, did we enjoy them!
He ended up running around the big play area with me following behind, climbing up and then going down the slides some more. We even found a pair of small slides where could go down at the same time, which was good for a laugh. When you're an adult, you sometimes forget how much fun a simple slide can be. Luckily kids are there to remind us.
I'm a little bit behind on my 2018 Goodreads Reading Challenge, but as we're now a month past the halfway mark of 2018, I thought I'd do a quick roundup of my favourite three books of the first half of the year:
The Divide, by Jason Hickel: I think about this book very often. It clearly explains why there is global inequality and that development aid is not the solution.
The Year of Less, by Cait Flanders: A delightful little book that describes our struggles with consumerism, why we do it and how to stop.
Jupiter War, by Neal Asher: the final book in the Owner trilogy, a heavy sci-fi series full of chaos and destruction. Not for the faint of heart.
“In the US, the portion going to the top 1 per cent more than doubled from 8 per cent in 1980 to 18 per cent today. Britain witnessed a similar jump during this period, with the share claimed by the richest growing from 6.5 per cent to 13 per cent.” ― Jason Hickel, The Divide ―
It's been more than two weeks after my last update on getting the USB host shield working with Espruino. I decided to work on it a bit more yesterday so that it doesn't end up in the abandoned projects drawer.
After I discovered earlier this week that the TUSB3410 chip won't work unless you upload firmware into it first, I decided to change tactics and attempt connecting to a different chip instead. A week ago I got my Node.js user-space driver for the Silicon Labs CP2102 chip working[1]. This chip is inside the OneTouch VerioIQ glucose meter, so I plugged the meter into the USB host shield and started swapping out the TUSB3410 code for CP2102 code.
It again didn't work at first. I connected the logic analyser and noticed that there still wasn't any USB bulk in transfers happening, even though everything sent was being acknowledged by the device. However, there was a glimmer of hope as I discovered some data packets in the bitstream that looked like what I was expecting to receive. So the data was coming back, but my bulk in transfer wasn't created correctly to capture it.
After looking through the code some more, I came to the conclusion that the issue was with the data toggles used by the MAX3421. I finally figured out that I need to keep track of separate toggles for each endpoint, and as soon as that was in place I was greeted with this:
I was able to see data being returned in a bulk in transfer! Amazingly, I'm finally getting data back from a device connected to the USB host shield on my Espruino Pixl.js. I guess this could've happened much sooner if I went with the CP2102 first instead of the TUSB3410.
Now, the next step is to get some actual blood glucose data from the meter and visualise it on the Pixl.js screen. If all goes well, that should be much easier!
After I wrote yesterday's post, I decided to give it one last shot and at least try and implement the workaround. And guess what, it worked! I can successfully connect to a TUSB3410 chip on macOS using Node.js, update its firmware and read data from the device it's connected to. Woot!
I have to say, being able to finally use Wireshark on macOS with High Sierra made things a lot easier. Without USB traces from Wireshark I wouldn't have guessed that the device wasn't being reset by macOS after the firmware was updated.
It seems that libusb_reset_device has been broken on macOS since El Capitan. Changing
works great. It requires recompiling libusb in node-usb and then running npm install --build-from-source in node-usb. I've reported the bug to libusb, so let's wait and see what they say.
Yesterday I described how the first step when connecting to a TUSB3410 chip is to upload firmware to it. After losing quite a few hairs with my TI TUSB3410 user-space driver not working on macOS while working perfectly fine on Linux, I've come to a few conclusions.
After the firmware is sent to the TUSB3410 chip, it stops responding until you perform a soft reset. The only problem is that since El Capitan, macOS ignores soft resets from libusb, the library used by node-usb. I have verified this by looking at the Wireshark traces. Nothing appears on the bus after the firmware is sent.
There seems to be a workaround, which involves re-enumerating the device instead of a soft reset, but this means modifying the libusb library itself. I think I've spent enough time on this for now, and will maybe look into again in future.
I think I have finally figured out the problem with my TUSB3410 driver, including why it's not working on my USB host shield. In short, the chip requires that you upload its firmware into the chip every time it is plugged in.
I noticed today that sometimes when I plug it into a host PC, there is only one USB configuration with only an OUT endpoint. There should be two configurations with the second one having multiple endpoints, including an IN endpoint.
This made me realise that it's possible that when I plug the device into a system with a working kernel driver, that driver is loading the firmware into the chip, so that when I then unload the kernel driver I see the two configurations when connecting with the user-space driver.
To confirm this I added the ti_usb_3410_5052 Linux kernel driver to the kernel module blacklist (/etc/modprobe.d/blacklist.conf) to prevent it from loading. I then verified this by running usb-devices[1] and checking that it says Driver=(none) next to the device description.
I then checked the number of configurations and low and behold, there was only one this time.
Luckily Texas Instruments has made the source code for their macOS driver available online, even though the macOS driver itself was never officially released. The source code also contains the chip firmware, so I just had to look at the source code to see how to write the firmware to the chip. Basically you just write a bulk out transfer, with the firmware bytes prepended by three special bytes: [size & 0xFF, (size >> 8) & 0xFF, checksum & 0xFF], where size is the length of the firmware byte array, and checksum is just adding all the bytes in the firmware array together.
I've got this working on Linux now. macOS is the next step, and then I can go back to my Espruino code and get it working on the USB host shield.
So after getting the CP2102 user-space driver working on Friday, I started on writing a user-space driver for the Texas Instruments (TI) TUSB3410 chip. This is the same chip that I'm writing a driver for on the USB host shield, so now I'm porting my WebUSB version over to Node.js.
I haven't been successful in getting data back from the device just yet, but this should be much easier to debug than on the embedded USB host controller chip, so I hope to have an update tomorrow with some good news.
I've come down with some kind of stomach bug. I've been feeling horrible all day, but I am hoping that whatever this is will be over quickly.
I have also been thinking a lot about this Twitter thread today. While it's true that conventional gardening techniques will not provide the yield required to feed ourselves and our families, I do wonder if the increased yield from hydroponics, and the ability to grow year round, will make this feasible?
There are lots of things to do in the new house before we can move in. One of these is cleaning the carpets. Usually we get a company to do it, but this time round I wanted to see if I could it myself.
Here in the UK you can rent carpet cleaning machines from most supermarkets and hardware stores. They're all from the same company, Rug Doctor. You pay around £24 to rent it for 24 hours, and then pay another £10-£15 for carpet detergent[1].
The machine was easier to use than I expected. The most time-consuming part is refilling it with warm water and detergent each time. The actual cleaning part consists of pushing a button and pulling it across the carpet, timing it right to release the button before you turn so that you don't make the carpet too wet.
All in all, it was a tiring but reasonably rewarding experience in doing it myself, kind of like putting together Ikea furniture. I guess I might just do it myself again next time round.
Yesterday I mentioned starting on a Silicon Labs CP2102 user-space driver for Node.js. Well, I just managed to successfully read data from the device! The source code for the driver is already on GitHub, but I still need to write up usage instructions and do some testing.
I wrote it as a kind of WebUSB to node-usb interface, so that I can re-use parts of the code to easily port WebUSB drivers over to Node.js, or maybe I could even package the interface up as an NPM package? Then you can re-use your WebUSB drivers in Node.js by just by adding one line of code to import this package.
One thing that I found non-intuitive was that after sending a request for data as a USB bulk out transfer, you then either need to create another USB bulk in transfer to read data, or use node-usb's startPoll() function, which essentially starts polling for data on the IN endpoint. Also, if you're using endpoint 1, 0x01 is OUT and 0x81 is IN. You may find this code useful if you're trying to create a USB request type: