Saturday, May 24, 2025

[Tech] What do SATA/AHCI SStatus and SControl mean?

 If you're troubleshooting a SATA drive connection in Linux and you run into errors like this:

  [14465.577496] ata2: SATA link down (SStatus 4 SControl 300)

  [14476.281867] ata2: SATA link down (SStatus 4 SControl 3F0)

 You will likely have trawled the open Internet for solutions and found wonderful advice like "check your cables" and "hard drive is dying". In one case you even get the odd "you dirty boy, elsewhere in your dmesg you loaded a non-GPL module!"

None of it, however, actually attempts to understand *the error message itself*!!

Of course, this is Linux Land, so "just read the source" is the general ethos, so I did. Hopefully I can spare you the pain.

In Linus' Github mirror, you can find this section:

https://github.com/torvalds/linux/blob/b1427432d3b656fac71b3f42824ff4aea3c9f93b/drivers/ata/libata-core.c#L3190 

You don't have to click that, though:

    if (sata_scr_read(link, SCR_STATUS, &sstatus))
        return;
    if (sata_scr_read(link, SCR_CONTROL, &scontrol))
        return;

    if (ata_phys_link_online(link)) {
        tmp = (sstatus >> 4) & 0xf;
        ata_link_info(link, "SATA link up %s (SStatus %X SControl %X)\n",
                  sata_spd_string(tmp), sstatus, scontrol);
    } else {
        ata_link_info(link, "SATA link down (SStatus %X SControl %X)\n",
                  sstatus, scontrol);
    }

So what this message is reporting is merely the hardware register values from the SATA device itself when this function is called. Neat.

So, what are these registers? Well:

https://github.com/torvalds/linux/blob/b1427432d3b656fac71b3f42824ff4aea3c9f93b/drivers/ata/ahci.h#L124

     PORT_SCR_STAT        = 0x28, /* SATA phy register: SStatus */
     PORT_SCR_CTL        = 0x2c, /* SATA phy register: SControl */

The SATA register interface is defined as part of AHCI. From Intel's AHCI spec (thanks, Wikipedia!):

3.3.11 Offset 2Ch: PxSCTL – Port x Serial ATA Control (SCR2: SControl)

3.3.10 Offset 28h: PxSSTS – Port x Serial ATA Status (SCR0: SStatus)

In my case, SStatus of 4 means:

4h Phy in offline mode as a result of the interface being disabled or running in a
BIST loopback mode

So, the physical connection part of the SATA controller is off for some reason.

Also, for SControl: 

300h: no detection or init requested, no speed negotiation restrictions, Partial and Slumber sleep disabled

3F0h: no detection or init requested, RESERVED, Partial and Slumber sleep disabled

Unfortunately this doesn't also print SCR1 SError, so it's hard to say what actually went wrong.

Saturday, April 12, 2025

A Letter

 Dear Doctor,

 It would seem that I'm here for the same thing I was here for a decade ago, when you said it would be fine, that it's very manageable, just do these things and don't worry.

Those things didn't work. Well, they did work! But I didn't do them consistently, so my body didn't learn and grow, so they didn't have the desired work.

I know this is frustrating for you. You have all of the research and training of your profession available to you, pointing to the pattern of healing that best fits my circumstance. With such a clear path, you still watch me come back asking for help after not really taking it.

Take a deep breath. Feel the frustration, the rage, the impotence. Let it flow. Let it pass.

Then walk with me.

On this path we should be out of shelling range. Do you see these trenches? The gnawed, chewed, desolate no-man's land? The emplacements? Their complements on the far side? Here, you can borrow my binoculars.

The line hasn't moved in ten years, yet we fight. Wave after wave of all the little packets of executive function I can muster, mowed down day after day. These, my men, trained, ready, willing, enough to hold the line but never enough to move it. A field of corpses of days, weeks, months, years past, but no progress, just piles.

Walk with me again.

It's hot here. The jungle thrives on the heat and the moisture. They say that our objective is that hill, just over there.

As we walk, notice the tenuous grasp we have. Forest and plains gear rots in the jungle's stew, so we improvise everything. Every foot of paved, level, or open ground cost so, so much. Lives, opportunities, truncated futures relegated to never being, entire barges of materiel.

Up here is a trail into the jungle towards the hill. Note the ruts, the gravel, the slashes and paint on the trees. Out here it's seems like barely a walking trail, yet if you stub your toe don't look down. The sunken truck shoring up this square foot mocks you with its empty, dead eyes, only a bit of fender and bumper and cowling reminding you that there are no masters in the swamp, only the swamp and what the swamp decides to swallow. I think the driver escaped this one. Maybe. Don't dig.

The missions into the swamp sometimes come back with interesting stories and close calls or even strange discoveries. The others find unmarked graves to record their progress...and their inventory.

Yet X marks the spot, and as we can, we try. Occasionally the jungle provides, but usually it sides with the swamp.

So as you cradle your grief that a patient didn't follow the golden path to healing, please find it in your heart to cry for me too. Only recently did we figure out machetes that don't blunt after two strokes, and the promise of air support whispers in the wind. There may even be peace one day. One day the golden path will be clear.

It is not clear today.

Sincerely,

Your Patient

Sunday, February 9, 2025

[Tech] ESPHome, Raspberry Pi, PlatformIO, and "sh: 1: xtensa-esp32s3-elf-g++: not found"

If you have bumped into this locked thread:

https://github.com/esphome/issues/issues/3904

You may be facing NEITHER a PlatformIO bug NOR an ESPHome bug. IF you are on a non-64-bit Raspberry Pi 2 (so, most of them, I think, but some were 64-bit-capable), it might just be that the toolchain was linked incorrectly for Ubuntu (and probably all Debian-based distros). The easy way to tell is:

$ uname -a
Linux pi 5.15.0-1071-raspi #74-Ubuntu SMP PREEMPT Fri Jan 17 12:09:29 UTC 2025 armv7l armv7l armv7l GNU/Linux

If you see 'aarch64' or you aren't on Ubuntu 22.04, then the thread is 100% a better source of info than this post.

Of interest is the first error in this post:

https://github.com/esphome/issues/issues/3904#issuecomment-1552547642

$ ./.esphome/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-g++
-bash: ./.esphome/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-g++: No such file or directory

We can elaborate with strace:

$ strace ./xtensa-esp32s3-elf-g++
execve("./xtensa-esp32s3-elf-g++", ["./xtensa-esp32s3-elf-g++"], 0xbedd91a0 /* 27 vars */) = -1 ENOENT (No such file or directory)
strace: exec: No such file or directory
+++ exited with 1 +++

See, this means that the ENOENT comes from very, very early in process start. In my experience (please don't ask), this means the loader is missing, which, indeed, it is:

$ file xtensa-esp32s3-elf-g++
xtensa-esp32s3-elf-g++: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=3b97cade4ee2d3b55df21b3dd333eb95dd42f5dd, stripped

$ file /lib/ld-linux.so.3
/lib/ld-linux.so.3: cannot open `/lib/ld-linux.so.3' (No such file or directory)

I was worried that the EABI5 and armv7l mismatch was going to cause problems, but no, as mentioned here:

https://github.com/esphome/issues/issues/3904#issuecomment-1554071496 

it's just a matter of letting the kernel find the dynamic loader where the ELF binary says it should be:

$ sudo ln -s /lib/arm-linux-gnueabihf/ld-linux.so.3 /lib/ld-linux.so.3

In my case that was actually:

$ sudo ln -s /lib/arm-linux-gnueabihf/ld-linux.so.3 /lib/ld-linux.so.3 

So, maybe it could be considered a PlatformIO bug that it pulls an Espressif toolchain with bad dynamic linking configuration, an Espressif toolchain bug that their toolchain was not available linked for Ubuntu, or a Linux bug that dynamically linked binaries are a kludge. Either way, acidic and vague as they are on that thread, [ssieb] is right that this is NOT an ESPHome bug.

Wednesday, June 5, 2024

[Tech] LimeSDR on ARM64 Windows (almost)

I recently got a LimeSDR Mini v2.0, a software-defined radio receiver-transmitter that's open-source, open-hardware, and generally awesome. (OK, that last bit is an opinion--I did back the CrowdSupply project, so I definitely thought it was Neat.)

Since ARM64 Windows is, shall we say, an intrinsic part of my day job, I naturally tried using the LimeSDR on the Lenovo ThinkPad X13s I use. It didn't work.

So, what's a software developer to do when an open-source project doesn't work?

Make it work and contribute back the changes, of course!

Thursday, November 23, 2023

[Technical] Using rtl_433 with Salter temperature probe

 So, you bought a Salter brand oven thermometer, FCC ID 2ATK8-BS201, and it has a nice removable remote that listens to radio chirps from the base to report the temperature. Great! It's a nice, functional product, even if the FCC ID doesn't seem to exist. (!)

If you want to use it with rtl_433 and an SDR, though, you'll find that it reuses the ThermoPro TP12 protocol under the hood.

Well, that's easy enough--except it reports two temperatures, and neither of them seem remotely correct. If you watch closely, though, you'll find that "temperature_1_C" is exactly 30 degrees C over the temperature reported on the remote.

I haven't figured out what temperature_2_C is yet, but it does seem to track with temp 1 at least a little.

Thursday, September 28, 2023

[Tech] GPS reception on Raspberry Pi 2 with RTL-SDR

(Nope, still not working yet.)

 

I have an RTL-SDR dongle and an active GPS antenna, so I'd like to attach them to my wee little Raspberry Pi 2 and try and catch some signals with them.

Since I have an RTL SDR Blog v3 dongle, the hardware isn't really that interesting.

What is interesting is the software. My little Pi is not running x64 Windows; in fact, it's running Ubuntu 22.04 Server. I'd like this data reception to be self-contained if possible, so rtl-tcp is out this round.

The RTL SDR Blog has a post about this:

https://www.rtl-sdr.com/rtl-sdr-tutorial-gps-decoding-plotting/

This is from 2017 and points to a neat project:

https://www.github.com/taroz/GNSS-SDRLIB

This repo contains a set of Windows tools and a single Linux CLI tool that doesn't build out of the box.

  1. Per `cli/linux/readme.md`, you need to edit the makefile to select your radio.
  2. You also need to remove -DSSE2_ENABLE, since that won't work on Arm.
  3. Next you need to install libfftw3-dev: `sudo apt install libfftw3-dev`
  4. There's a bug in stereo.h, where STEREO_globalDataBuffer is defined in a header, leading to extra conflicting definitions at link time. I marked it extern in the header and added it to stereo.c, which probably isn't the best place for it.
  5. There are checked-in library binaries that need to be provided for the new platform.
    1. libfec appears to live on at https://github.com/quiet/libfec and is handily installed via `sudo apt install libfec-dev`. Switch the .a file on the LIBS line out for `-lfec`.
    2. libnslstereo is not related to libnsl. I haven't yet been able to track it down, but stereo.h suggests it's just another RF front-end. Since I'm using an RTL-SDR instead, I dropped it from the OPTIONS, LIBS, and OBS lines.
    3. librtlsdr: from your local RTL-SDR build based on https://github.com/rtlsdrblog/rtl-sdr-blog, copy build/src/librtlsdr.a over src/rcv/rtlsdr/rtlsdr.lib and change LIBS+=-lrtlsdr to LIBS+=../../src/rcv/rtlsdr/rtlsdr.lib
      1. FCIB has earned it's 'F' in this repo. Holy cow.

A quick `make -j4` and now we have a binary that, when copied into the `bin` folder next to its INI file, prints:

$ ./gnss-sdrcli
GNSS-SDRLIB start!
error: rcvinit 

Yay!

Editing bin/gnss-sdrcli.ini to point to frontend/rtlsdr_L1.ini seems to be a good start. The RTL-SDR fires up, but then the program crashes. Adding some tracing shows that it's during RTL-SDR init, so maybe the headers and static lib don't match and that's breaking things.

Sunday, July 23, 2023

ingots

 It was cleanup time again.

The plant operator was supposed to be good enough at his job to avoid this, but here I was again, shovelling lumps of waxy rage and slivers of regret and empty bubbles of crystallized disappointment into the crucible.

The heat would slowly soften them, then they would melt. I'd then stir the lumpy goo with a big glass rod until it was just thick goo, and then I'd squeeze it out into the molds. They'd cool there, wafting shimmers of heat into the room and across the ceiling, then solidify. The heat would get pretty awful, but at least they shrank away from the sides of the ingot molds. Stacking came next; the far wall had row upon row of these little ingots, stacked away. No one knew what to do with them; they were inert weight, bending space-time ever so slightly more than their surroundings, crying out to be used and refusing to even speak.

When the last bar was cast, set, and stacked, it was time to cool off and clean up. The bits that splashed, burbled, offgassed, or splattered on me as I worked needed to come off and go in the hopper for the next run--I wasn't allowed to leave the oppressively hot room with it on me, so I started working the intraplant signalling system. It was after hours; the break room only had a few people in it, screaming past each other in an attempt to, what, hear themselves scream? Make the pain stop? Make the pain multiply? Certainly not scrub or scrape someone else's protective gear. The control room was a skeleton crew with far too much to do; no spare cycles there. The engineering bay was noisy with the automatons left overnight to fill the silence, the few nocturnal engineers too engrossed to look up at the plant status lights.

And why should they? I'm a little cog cleaning up a mess that shouldn't, on the face of it, exist.

So I use the self-filtering shower to get most of it off, stopping every few minutes to let the solvent slip through the filters, then emptying the filters into the hopper. After a few cycles of painsstaking scrubbing and filtration, I would cast one last ingot, set the tongs down, and stare at it cooled. I had to wonder if some of it was my own, and not from the industrial processes the plant was charged with.

Still, it was done. I could go listen to the vain shrieking or wander, unseen, through the engineering department. At least the ingots were stacked. For now.