C GPIO
#21
(09-01-2016, 05:29 AM)MarkHaysHarris777 Wrote:
(09-01-2016, 05:08 AM)martind1983 Wrote:  Very nice and comprehensively answered and also works as you know.
However, thank you man Big Grin

hi,  just for clarification, in your judgement then, is the current manual correct in what it states ( in regard to this thread ) or does it have omissions that we could document more throughly so that others don't have this issue.

In other words, is the above comprehensive explanation in the manual necessary to make sense of what the current manual states, or is the current manual complete as it stands ( in your opinion )?   Thanks.
Hi Mark

In my opinion. When the programmer uses correct type casting. What I haven't done in my first case you can easily access all registers in the chip. As our colleague implied to us. This works perfectly.

I just wanted to say for example: If PIO address 0x01c20800 would be possible to map (as it is not possible because of page size alignment). It would be easily possible to access any register from PIO peripheral just by adding its order number to mapped PIO address. Let's say

PB_CFG0_REG register you could access by adding 1 to PIO base address what is 0x01c20800, like normal pointer arithmetic. However, as you cannot map PIO base address, you can only map CCU address what is 0x01c20000 and there are not any registers you could manually count like I described in previous lines or maybe it would be possible but it would be laborious. The aforementioned way KnReLe did is very goog and as I said you should be able to access any register in the chip.

I should review my typecasting a bit Big Grin

Thank you to all Smile
  Reply
#22
martind1983
In my opinion. When the programmer uses correct type casting. What I haven't done in my first case you can easily access all registers in the chip. As our colleague implied to us. This works perfectly.

I just wanted to say for example: If PIO address 0x01c20800 would be possible to map (as it is not possible because of page size alignment). It would be easily possible to access any register from PIO peripheral just by adding its order number to mapped PIO address. Let's say

PB_CFG0_REG register you could access by adding 1 to PIO base address what is 0x01c20800, like normal pointer arithmetic. However, as you cannot map PIO base address, you can only map CCU address what is 0x01c20000 and there are not any registers you could manually count like I described in previous lines or maybe it would be possible but it would be laborious. The aforementioned way KnReLe did is very goog and as I said you should be able to access any register in the chip.

I should review my typecasting a bit Big Grin

Thank you to all Smile

(not sure what happened to the quoting )

Actually, if you want to automate the masking and handling of fact that the IO-address is not aligned to the page size, something like this would do:

/* Base address for PB-PH */
#define GPIO_BASE_ADDR_PB 0x01c20800

/* Base address for PL */
#define GPIO_BASE_ADDR_PL 0x01f02c00

Then in the function there could be something like this using variables (or even passing in the port_io_base as an argument):

    uint64_t addr_offset; 
    uint64_t addr_start;      /* page-aligned start-address of mmapped space. */
    uint64_t page_size;      /* Page-size from system, it reports 0x1000 here. */
    uint64_t page_mask;    /* Mask to separate out page-alignment bits */
    uint64_t port_io_base;  /* input GPIOs base-address, doesn't have to be page-aligned */


    port_io_base = GPIO_BASE_ADDR_PB;  /* For example for ports PB-PH */

    page_size = sysconf(_SC_PAGESIZE);     /* 0x1000 */
    page_mask = (~(page_size-1));                /* 0xFFFFFFFFFFFFF000 */
    addr_start = port_io_base & page_mask;     /* gives the page-aligned start address 0x01c20000, last 24 bits are 0 */
    addr_offset = port_io_base & ~page_mask;   /* mask with 0FFF so we get the 0800 offset into the page */

Then to the mmap (after the opening of the file of course)

    p_mem = mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start);

Later you aim at the various registers, with the offset included, pretty much the same as before except no longer hardcoded:

    offset = addr_offset + 0x48;  /* Will aim at the first of the PC control registers, which controls PC7--PC0 */
    gpio = (volatile uint32_t *) ( (char *) (p_mem) + offset);

Or slighlty more compact as that extra variable offset isn't really necessary

    gpio = (volatile uint32_t *) ( (char *) (p_mem) + addr_offset + 0x48);

With this masking, this will work on any of the register addresses.
  Reply
#23
(09-01-2016, 08:52 AM)KnReLe Wrote: martind1983
In my opinion. When the programmer uses correct type casting. What I haven't done in my first case you can easily access all registers in the chip. As our colleague implied to us. This works perfectly.

I just wanted to say for example: If PIO address 0x01c20800 would be possible to map (as it is not possible because of page size alignment). It would be easily possible to access any register from PIO peripheral just by adding its order number to mapped PIO address. Let's say

PB_CFG0_REG register you could access by adding 1 to PIO base address what is 0x01c20800, like normal pointer arithmetic. However, as you cannot map PIO base address, you can only map CCU address what is 0x01c20000 and there are not any registers you could manually count like I described in previous lines or maybe it would be possible but it would be laborious. The aforementioned way KnReLe did is very goog and as I said you should be able to access any register in the chip.

I should review my typecasting a bit Big Grin

Thank you to all Smile

(not sure what happened to the quoting )

Actually, if you want to automate the masking and handling of fact that the IO-address is not aligned to the page size, something like this would do:

/* Base address for PB-PH */
#define GPIO_BASE_ADDR_PB 0x01c20800

/* Base address for PL */
#define GPIO_BASE_ADDR_PL 0x01f02c00

Then in the function there could be something like this using variables (or even passing in the port_io_base as an argument):

    uint64_t addr_offset; 
    uint64_t addr_start;      /* page-aligned start-address of mmapped space. */
    uint64_t page_size;      /* Page-size from system, it reports 0x1000 here. */
    uint64_t page_mask;    /* Mask to separate out page-alignment bits */
    uint64_t port_io_base;  /* input GPIOs base-address, doesn't have to be page-aligned */


    port_io_base = GPIO_BASE_ADDR_PB;  /* For example for ports PB-PH */

    page_size = sysconf(_SC_PAGESIZE);     /* 0x1000 */
    page_mask = (~(page_size-1));                /* 0xFFFFFFFFFFFFF000 */
    addr_start = port_io_base & page_mask;     /* gives the page-aligned start address 0x01c20000, last 24 bits are 0 */
    addr_offset = port_io_base & ~page_mask;   /* mask with 0FFF so we get the 0800 offset into the page */

Then to the mmap (after the opening of the file of course)

    p_mem = mmap(NULL, page_size * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start);

Later you aim at the various registers, with the offset included, pretty much the same as before except no longer hardcoded:

    offset = addr_offset + 0x48;  /* Will aim at the first of the PC control registers, which controls PC7--PC0 */
    gpio = (volatile uint32_t *) ( (char *) (p_mem) + offset);

Or slighlty more compact as that extra variable offset isn't really necessary

    gpio = (volatile uint32_t *) ( (char *) (p_mem) + addr_offset + 0x48);

With this masking, this will work on any of the register addresses.

Thanks KnReLe

Also very nice solution Wink
  Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  RPi.GPIO python module for Pine A64/A64+ aquilegia 98 129,720 12-15-2022, 08:40 PM
Last Post: Fadazo
  fm transmitter with gpio weasel18 2 4,751 09-10-2019, 04:28 AM
Last Post: desai_amogh
  How to use dts or other setup to declare gpio pin Interrupt (e.g. a button)? dkebler 1 3,546 06-12-2019, 10:37 AM
Last Post: dkebler
Lightbulb Sample GPIO codes highlighting RPi.GPIO-PineA64 and the PI bus MarkHaysHarris777 6 10,954 06-07-2019, 12:37 AM
Last Post: tllim
Star GPIO, SPI and I2C C++ Lib databit 7 11,039 02-04-2019, 05:45 AM
Last Post: Jeff R
Information Howto: Controlling Pine64 GPIO via the filesystem (sysfs) on linux pfeerick 4 11,752 01-24-2019, 03:36 AM
Last Post: Fifth
  GPIO and SPI SamR1 20 31,152 03-15-2018, 10:32 AM
Last Post: jomoengineer
Question GPIO shockr 7 14,578 03-11-2018, 01:52 AM
Last Post: jomoengineer
  Read GPIO problem shworker 14 20,928 08-17-2017, 01:21 PM
Last Post: martinayotte
  GPIO fiq capability joseph 3 6,007 11-10-2016, 06:07 PM
Last Post: joseph

Forum Jump:


Users browsing this thread: 1 Guest(s)