Wednesday, November 26, 2014

Trying out a mini logic analyzer

I just got a small and inexpensive logic analyzer from dx.com. Basically, it contains a CY7C68013A microcontroller and 74HC245 buffer chip, and you can upload firmware which makes it into a logic analyzer.

I used sigrok PulseView. First I tried it in Windows. It's easy to install the driver using the included Zadig executable. After that, PulseView tended to crash on startup if the logic analyzer was connected. I only got it to run a few times. Also, it seemed to lock up sometimes when capturing for a second or third time. I expect this is due to bugs in the Windows version of PulseView, and not due to a problem with the hardware.

Here's a decode of a NEC protocol IR remote. I couldn't get it to work at the default 20 kHz sample rate, even though that should have been fast enough. It worked at 100 kHz.
Here's some 9600 baud serial communication. This is also at 100 kHz. It also worked at 20 kHz sampling if I set the decoder baud rate to 10000. Problems with 20 kHz are understandable though, because it's just a bit over twice the baud rate.
After this I rebooted into Linux because the Windows problems were getting too annoying. Installing sigrok was easy, because a Ubuntu package was available. I didn't have any problems in Linux. Here's some SPI. The Stellaris LaunchPad is communicating with an nRF24L01+ module and writing to some registers. This is at the maximum sample rate of 24 MHz.
As you can see, with a small piece of hardware you can order from China for $10 and some free software, you can have a 24 MHz logic analyzer which will decode protocols for you. That's truly impressive!

Saturday, November 15, 2014

If nRF24L01 modules don't work, add decoupling capacitors

I got two nRF24L01+ modules and tried to establish communication between the MSP430 and Stellaris LaunchPads. SPI communication worked, and I was able to read and write registers, but all attempts at wireless communication were a total failure. I even tried a kind of promiscuous mode, where I was getting data, but it all seemed to be garbage with no trace of the packets I was transmitting. Something was definitely being transmitted according to the chip's received power detector, though it was suspiciously spread out onto adjacent channels.

After wasting a few hours trying to figure out what was wrong with the software and finally taking a break, I got the idea to try adding bypass capacitors. They made everything work. The modules do have C8 and C9 which are supposed to be 1 nF and 10 nF respectively, but those are clearly not enough when the power supply wires are long. I just used some small electrolytic capacitors I had around, 56 µF on one module and 33 µF on another. Tantalum capacitors would be a better choice because of their smaller size and good high frequency performance.

Saturday, November 08, 2014

Chain booting Linux from Windows using Darwin chain0

EasyBCD can create a Windows boot menu entry for Linux, using GRUB installed in its partition. This copies the boot sector of the selected partition to C:\NST\nst_linux.mbr and sets up an entry to boot via that file. This works, but it can stop working if upgrades are installed in Linux and the boot sector changes. In that case, the boot sector needs to be copied to that file again. Deleting and re-creating the menu entry in EasyBCD will accomplish that.

It would be better to read the boot sector directly, but I don't think Windows supports that. Another alternative is to use a boot sector file which finds and loads the real boot sector. This approach is used when loading Mac OS X or Darwin via chain0. You can obtain a version of chain0 at C:\NST\nst_mac.mbr by setting up a Mac OS X MBR boot entry in EasyBCD. The version I have has an MD5 value of cfca64f400ef99e89b51e59bcb697137. I patched it to search for the Linux partition instead of OS X and used that version as nst_linux.mbr:

C:\NST>fc /b nst_mac.mbr nst_linux.mbr
Comparing files nst_mac.mbr and NST_LINUX.MBR
0000008A: AB 83
00000090: A8 83
00000096: AF 83

It can search for three different partition types, but I only need to search for one so I set them all to 83 hex. This can successfully boot Linux from the first partition in my extended partition. If you have a more complicated setup, you may need a different version of chain0 with a fix for accessing other partitions in the extended partition.

Yellowish light seems brighter, and bright bluish light is more annoying

The brightness of the 100W cool white LED is confusing. After being for a while in a room illuminated by it, the room seems quite dim. Going away and coming back shows that the room is in fact very bright. A 300W halogen torchiere is probably dimmer than the LED, but the room seems brighter when lit that way, and that feeling of brightness doesn't go away.

The LED array itself seems extremely annoyingly bright. It is so bad that I can't stand it even in the farthest peripheral vision, and I will walk sideways with my back turned to it to avoid seeing it.  The effect reminds me of HID headlights, but it's even worse. It's much worse than the sun or high power halogen lights.

I'm also reminded of how brown sunglasses affect perceived brightness. Their darkened lenses obviously decrease real brightness. However, on a bright sunny day they only seem to reduce the unpleasant aspects of excessive brightness, and they can even increase perceived pleasant brightness.

This gives me some ideas. Does yellowish light trigger pleasant feelings of brightness, and does bluish light trigger unpleasant feelings of excessive brightness? Does yellowish light constrict pupils less than bluish light?

Friday, November 07, 2014

Trying out a cheap Chinese 100W LED array

Recently I found that Chinese 100W LED arrays cost less than $5 on eBay, so I had to try one out. The LED array arrived in less than a month in a padded envelope with no other protection. This is not right, because white LEDs are static sensitive, but I guess you can't expect much for $5, and the LED works. Here's the LED at very low power:
Note how the LEDs have unequal brightness. One whole row is brighter, presumably because the dark LED in that row has greater forward leakage and a low voltage drop across it. This all looks bad, but it's normal at low power. Using higher current and a low PWM duty cycle would probably produce more uniform results, if that was needed.

The biggest heat sink I had was a Slot-A Athlon heat sink. After mounting it the first time, without paste just to check the fit, I could see light between the LED and the heat sink. There were high spots at the plastic-filled holes and slots in the LED's metal plate. I don't think the plastic was high; it seems more like the metal was distorted by punching operations. The whole thing was also warped on a larger scale. After sanding it with fine sandpaper on a piece of glass, I got a much better fit and mounted it.
Note how the LEDs have very similar brightness now at higher power. The LED is a bit dirty from Brasso, which was probably unnecessary. Fine sandpaper was good enough.

Then there was the question of how to drive the LED. I have a power supply from an old Fujitsu SMD hard drive, with -12V and +24V outputs, giving 36V, which is more than enough for the LED. I set up some primitive linear current regulation, using a 0.22 ohm resistor and Vbe of a small transistor. The transistor controlled the gate of a power MOSFET with a big heat sink. This works surprisingly well, though note that Vbe changes with temperature. It regulated the current to 2.7A and I measured 35V accross the LED.

The heat sink required some serious airflow to stay cool enough that I could keep my finger on it indefinitely near the LED. Fortunately that same SMD hard drive had two 8 cm fans, to which I added some cardboard ducting to concentrate the air. The power supply even monitors the fans, not via RPM but via thermistors which are cooled by airflow and heated by resistors.
The light coming from the LED is surprisingly hot. My fingers quickly feel burning hot within a few centimetres of the light emitting face, and heat can be felt much further away. It's not the soothing heat of an incandescent, but something more like the feeling of steam escaping from a pot. I guess that's because the infrared light from incandescent bulbs penetrates deeper than visible light.

The LED is also incredibly annoying to look at, and worse than the sun or even badly aimed HID headlights. It's totally unacceptable to have this LED even in the farthest part of my peripheral vision. At the same time, the room doesn't really feel very bright.

In the past I was thinking of retrofitting a powerful LED into a halogen torchiere which had a bad bulb socket. I didn't do it because I wasn't sure I could deal with the heat in an acceptable way. Two high speed fans are fine for experimentation, but a light I use every day should be fanless or at best have a slow speed fan. Instead I ended up fixing the torchiere, making new socket contacts from brass pluming screws.

Comparing light from the 300W halogen torchiere and the 100W LED operating at around 90W, I definitely prefer the torchiere. It makes the room seem brighter even though the LED might actually be a bit brighter. It's hard to compare brightness due to different colours and lamp positions, but I don't think this LED is capable of 9000 to 10000 lumens at 3A. The LED's colour is also somewhat weird. Colours which would normally seem close to white seem yellowish or purplish.

Overall, I'm not too impressed. The light I'm getting doesn't make me want to create a more permanent lamp or flashlight using this LED. It was fun to play with though, and certainly worth the $5.

Tuesday, November 04, 2014

Craig CVD601 Android stick


I got a Craig CVD601 Android stick at the XS Cargo closing sale for $30. Android devices which are designed to be hooked up to a TV interested me, but I didn't have enough faith in the idea to actually order one. This was cheap and a good deal even compared to ordering from China, so I decided to try it out.

The device came with Android 4.1 Jelly Bean and worked, but the WiFi is terrible. At the same location, my laptop gets a good signal but the CVD601 can only occasionally connect with a terrible transfer rate. Best results were on channel 2, but even that was not usable. I created an access point on my laptop, but that's not a permanent solution.

Rooting

I quickly decided that rooting is necessary, because I don't want to keep running into obstacles where I can't do something because I don't have root access. This wasted a lot of time because various methods I tried didn't work. Some rely on security bugs which were fixed in earlier versions, or are designed to only work with particular devices. Eventually I found Cydia Impactor, which rooted the device quickly and easily. I used Impactor_0.9.14.zip, with MD5 162761dcbe0b2c0ac08cfb86dea8d715. Then I manually installed SuperSU.

After rooting, I edited /system/default.prop, removing tethering and developer_options from ro.wmt.ui.settings_remove to enable those settings. ADB access was available before, but this makes some things more convenient. I will also enable Ethernet settings when I get the USB adapter. Note that /system is normally mounted read-only, so it needs to be remounted via "mount -o remount,rw /system" before making changes. When done with  changes, use "mount -o remount,ro /system" to make it read-only again.

Reverse tethering

Reverse tethering provides better network performance than wireless, but I had too much trouble getting it started, and I don't recommend wasting time on this. First, tethering needs to be enabled. If the option is greyed out, enable USB debugging first. Then, on the Android side, the rndis0 interface needs to be reconfigured. I never got "netcfg rndis0 dhcp" working, so I had to configure manually, with ifconfig and route. Windows contains the driver but requires an INF file. I used Microsoft's template customized with USB\VID_18D1&PID_0003.

Google Play

I also decided I had to install Google Play Store, because many apps are only available there. It's possible to download APK files and then install them, but that makes things more complicated. If simply installed like any other app, Play Store runs fine at first but crashes as soon as I try to download anything. After that, it keeps crashing on startup. This is because it doesn't have permission to install apps. The solution is installing it as a system app, by copying its APK to the /system/app folder with chmod 644. The app will also crash if its version is incompatible with the version of Google Play Services that is already installed. I installed FirmwareInstall/GoogleApp/system/app/Vending.apk from cvd601_602_firmware4.1.zip available on the Craig site. Then it updated both the store and the services app to the latest version, and everything worked fine after that.

Internals and the WiFi issue

Due to the WiFi problem and my curiosity I decided to open up the device:

 Here is a closeup of the RTL8188ETV based WiFi module. It is a USB device, but with 3.3V power. You can find PDF documentation for similar devices online. The pins below and to the left connect to the antenna. Their top narrow part is spring loaded.
Here is the antenna, note the indentations from where the pins connected. The left black part of the sticker has no metal underneath, and the right part is one solid sheet of metal. Antenna and ground are shorted together, with only that little slot between them. I wonder what kind of antenna this is, and how it works. RF seems like magic sometimes.
After experimenting with various wires connected to the pins, I found I got the best results with two quarter-wavelength wires placed 90 degrees apart. Then I cut the sticker in half lengthwise and glued the parts back on 90 degrees apart. This gave me a reliable connection to the router which was good enough for the web at least, but it didn't work the next day. Then it worked again after I squeezed the device near where the pins are. Maybe the pins don't make good contact? In any case, I don't want to waste more time on this, so I'll wait until I get the USB Ethernet adapter.

Kernel source and config

The 3.0.8 Linux kernel for WM8850 is available on GitHub. It includes binary modules from WonderMedia. The configuration file can be extracted from the kernel on the device. Here is the kernel config for your convenience. The kernels in the boot image, recovery image and cvd601_602_firmware4.1.zip are identical.

Friday, October 03, 2014

Booting GRUB from a logical drive via the extended partition

The master boot record (MBR) contains code which is loaded at boot time, and a table which can list up to 4 partitions. Any data partitions created here are called primary partitions, and booting from them should be possible. One of those partitions can instead be an extended partition, which contains the same type of table, with up to 4 partitions. Partitions inside the extended partition are called logical drives, and it may not be possible to boot from those.

I installed Linux on a logical drive. Due to known problems installing Windows service packs when GRUB is in the MBR, I refused to put GRUB there and instead put it in the logical drive containing Linux. GRUB was normally loaded by the Windows 7 bootloader.

Now I wanted to boot directly into GRUB, so I can use it to hide and unhide partitions and select between two versions of Windows. Making just the logical drive with Linux active did not work. The result was as if there is no active partition. It is possible to make the extended partition active, but grub-install refuses to install there, probably because grub-probe can't figure out the mapping for it.

I solved this by copying the code from the Linux logical drive boot sector to the first sector of the extended partition. It was simple, via "sudo dd if=linux_logical_drive_partition bs=446 count=1 of=extended_partition". The code is 446 bytes long, starting at the beginning of the sector. The rest of the destination sector contains information about partitions, which must not be overwritten. It is extremely important to use the right device names here. (They will typically be something like /dev/sda5, with the logical drive having a higher number than the extended partition.) Mistakes in dd commands writing to raw disk devices can cause unrecoverable data loss.

GRUB's first stage code doesn't care from where it's loaded. However, it does contain hard-coded sector locations, and if that needs to change it would have to be copied again in the same way.

Wednesday, May 14, 2014

GA-P35-DS3R fan control

The Gigabyte GA-P35-DS3R motherboard has a IT8718F chip. It can control the speed of 3 fans via PWM and monitor the speed of 5 fans. The chip also has 3 thermal sensor inputs, which can be read by software. The SmartGuardian feature allows any thermal sensor input to be used to automatically control any fan without software intervention. Fan speeds can also be controlled from software. A PDF datasheet is available.

The BIOS has options to enable CPU fan speed control, and to use voltage or PWM to control the fan. I'm using voltage. The stock Q6600 fan has a 4 pin connector and supports PWM, but PWM causes noise. Voltage can control the speed just as well without the noise.

The BIOS programs the SmartGuardian feature to control CPU fan speed, but it doesn't provide any options for changing that configuration. Both Linux and SpeedFan support the IT8718F chip, but neither can program the SmartGuardian feature. SpeedFan only has an option in the Advanced tab to switch a fan from SmartGuardian to software control, which allows SpeedFan to control its speed. At least for the second PWM output, SpeedFan may not properly re-enable SmartGuardian.

An 8718fans program allows changing of SmartGuardian and other fan-related settings in the chip. It also allows viewing of current settings.

This GA-P35-DS3L information seems similar or identical to the GA-P35-DS3R. CPU fan speed is measured via the first fan sensor, and controlled via the first PWM output. That page claims that the first PWM output controls CPU fan voltage and the third output controls CPU fan PWM, which I didn't test. The second fan output controls voltage on SYS_FAN2, the 4 pin fan connector near the DIMMs and 24 pin power connector.

The BIOS sets up CPU fan control by using the second temperature sensor to control the first PWM output. This is a sensor at the CPU, but not one of the internal core temperature sensors that can be seen in programs like Core Temp. The IT8718F chip cannot use such sensors, because they can only be read by software running on the CPU. The second sensor measures temperatures which are about 10°C colder than the cores. According to 8718fans, full fan speed would be reached at 66°C, which probably corresponds to core temperatures near 76°C.

The BIOS also sets up sensor one to control PWM output two with the same settings. This is probably not reasonable for a case fan, because sensor one isn't at a particularly hot location. Its normal temperature is near 40°C, and if it reached 66°C, hotter areas would overheat.

The IT8718F SmartGuardian algorithm uses a slope, essentially just setting fan speed based on a linear relationship with temperature with some smoothing features. This means temperature depends on load, rather than being controlled to a particular level. If a certain fan speed corresponds to a certain temperature at a certain CPU load and CPU load increases, temperature increases until a new equilibrium is found, with a higher temperature and higher fan speed.

I'm now using SpeedFan to control a case fan, but still letting SmartGuardian control the CPU fan. Maybe I will inject some code into the MBR or elsewhere to set up SmartGuardian for the case fan, because I perfer not depending on an application for fan speed control.