Skip to content
New issue

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

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

Already on GitHub? # 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

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

No branches or pull requests

2 participants