Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPi detection fails on rare, unknown editions of the Pi, suggest device-tree as first port of call #105

Closed
Gadgetoid opened this issue Jul 12, 2016 · 3 comments

Comments

@Gadgetoid
Copy link
Collaborator

From RPi.GPIO:

    if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")) != NULL) {
        // get peri base from device tree
        fseek(fp, 4, SEEK_SET);
        if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
            peri_base = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
        }
        fclose(fp);
    } else {

Is there any reason that rpihw.c couldn't look to the device-tree first, and then fall back to the current method? I think it would be a more robust solution, and would prevent an update being necessary for every single version of the Pi (old and new) that's discovered.

In addition to this, a more user-friendly error could be useful in place of the current failure mode, which looks something like:

RuntimeError: ws2811_init failed with code -1

The code -1 is returned for all exceptions which doesn't help.

@penfold42
Copy link
Contributor

I like this approach better - can you do a PR ?

@Gadgetoid
Copy link
Collaborator Author

Gadgetoid commented Jul 13, 2016

I need to figure out the other half of the puzzle- finding the videocore, which isn't consistently offset from the peripheral base.

#define PERIPH_BASE_RPI                          0x20000000
#define PERIPH_BASE_RPI2                         0x3f000000

#define VIDEOCORE_BASE_RPI                       0x40000000
#define VIDEOCORE_BASE_RPI2                      0xc0000000

Presumably it's there in /proc/device-tree-soc/ranges, or it could be found with:

#include <stdio.h>
#include <stdint.h>

static unsigned get_dt_ranges(const char *filename, unsigned offset)
{
   unsigned address = ~0;
   FILE *fp = fopen(filename, "rb");
   if (fp)
   {
      unsigned char buf[4];
      fseek(fp, offset, SEEK_SET);
      if (fread(buf, 1, sizeof buf, fp) == sizeof buf)
      address = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] << 0;
      fclose(fp);
   }
   return address;
}

unsigned bcm_host_get_peripheral_address(void)
{
   unsigned address = get_dt_ranges("/proc/device-tree/soc/ranges", 4);
   return address == ~0 ? 0x20000000 : address;
}

unsigned bcm_host_get_peripheral_size(void)
{
   unsigned address = get_dt_ranges("/proc/device-tree/soc/ranges", 8);
   return address == ~0 ? 0x01000000 : address;
}

unsigned bcm_host_get_sdram_address(void)
{
   unsigned address = get_dt_ranges("/proc/device-tree/axi/vc_mem/reg", 8);
   return address == ~0 ? 0x40000000 : address;
}


int main(int argc, char *argv[])
{
   uint32_t a1, a2;

   a1 = bcm_host_get_peripheral_address();
   a2 = bcm_host_get_sdram_address();

   printf("paddr=%x, baddr=%X\n", a1, a2);
}

Which was posted by Joan here: https://www.raspberrypi.org/forums/viewtopic.php?p=684084

@Gadgetoid
Copy link
Collaborator Author

Okay, the above code outputs the following:

  • Raspberry Pi 3 ( a02082 ): paddr=3f000000, baddr=C0000000
  • Raspberry Pi 2 ( a01041 ): paddr=3f000000, baddr=C0000000
  • Raspberry Pi Zero v1.3 ( 900093 ): paddr=20000000, baddr=40000000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants