dharanivel
Posts: 33
Joined: Sun Dec 16, 2018 4:36 am

How to find the address of gpio in raspberry pi zero

Wed Dec 19, 2018 6:08 pm

I dont know where to find the address of the gpio and how to use gpio for input and output. Can any one help me.. please


dharanivel
Posts: 33
Joined: Sun Dec 16, 2018 4:36 am

Re: How to find the address of gpio in raspberry pi zero

Thu Dec 20, 2018 3:31 am

I need to program in assembly language.
so can anyone help me.

Schnoogle
Posts: 91
Joined: Sun Feb 11, 2018 4:47 pm

Re: How to find the address of gpio in raspberry pi zero

Thu Dec 20, 2018 8:21 am

Hi dharanivel,

I guess this documentation: https://www.raspberrypi.org/app/uploads ... herals.pdf
is a very good starting point. However, the memory addresses mentioned in this document differ depending on the RPi model you are using.
If you do program in bare metal assembly than the base address should be 0x3F000000 for RPi 3 and above. So whenever you find an address in the document like 0x7E000000 and above you need to to replace with the mentioned 0x3F000000.
Page 89 starts talking about GPIOs. This should get you startet to set GPIOs as input/output and set them to high/low etc...

Hope this helps.
BR
Schnoogle

dharanivel
Posts: 33
Joined: Sun Dec 16, 2018 4:36 am

Re: How to find the address of gpio in raspberry pi zero

Thu Dec 20, 2018 8:32 am

thankyou but iam trying to use arm assembly language, the gpio address start from 0x20200000. can someone help me...

Schnoogle
Posts: 91
Joined: Sun Feb 11, 2018 4:47 pm

Re: How to find the address of gpio in raspberry pi zero

Thu Dec 20, 2018 10:42 am

Hi,

well you are right with the GPIO base address being 0x20200000 - but only on RPi 1 and 2 as far as I'm aware. From RPi 3 onwards it's 0x3F200000

The document provided gives you pretty much all the register addresses to drive GPIO propperly. Whether you access those addresses with ARM-ASM or C doesn't really matter. Use the language you favor.

Assuming you are able to read C code and you are able to translate into ARM-ASM than this repo could be a very good starting point to get the first LED blink ;)
https://github.com/dwelch67/raspberrypi ... /blinker01

BR
Schnoogle

dharanivel
Posts: 33
Joined: Sun Dec 16, 2018 4:36 am

Re: How to find the address of gpio in raspberry pi zero

Thu Dec 20, 2018 10:45 am

thankyou for your response. i will try it and i tell my feedback

bzt
Posts: 393
Joined: Sat Oct 14, 2017 9:57 pm

Re: How to find the address of gpio in raspberry pi zero

Thu Dec 20, 2018 11:06 am

dharanivel wrote:
Thu Dec 20, 2018 8:32 am
thankyou but iam trying to use arm assembly language, the gpio address start from 0x20200000. can someone help me...
I'm not sure what you're asking, since you've already found the GPIO address...

All MMIO peripherals have the same address, it's only the MMIO base address that changes for newer models: that's 0x3F000000 for Pi2B+ and above, and 0x20000000 for Pi1, Pi2 and Pi zero.

If you want to detect that in run-time, then you have to read the CP15 Main ID / MIDR_EL1 register, which has different values on each Pi models.

Code: Select all

mrc p15,0,r0,c0,c0,0
The return value should be interpreted like this. Bits [15:4] (CPU PartNo) tells you the Pi model, that should be 0xB76 for Pi zero. There's a cpuid tutorial thanks to dwelch67 (written in C, but shouldn't be a problem for you to convert it into Assembly).

Cheers,
bzt

dharanivel
Posts: 33
Joined: Sun Dec 16, 2018 4:36 am

Re: How to find the address of gpio in raspberry pi zero

Fri Dec 21, 2018 12:34 pm

there is total 53 gpio,but in rpi zero there is only upto 27 and i confused what happen gpio 1, 2 and 28 to 53.

User avatar
rpdom
Posts: 15601
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: How to find the address of gpio in raspberry pi zero

Fri Dec 21, 2018 1:00 pm

dharanivel wrote:
Fri Dec 21, 2018 12:34 pm
there is total 53 gpio,but in rpi zero there is only upto 27 and i confused what happen gpio 1, 2 and 28 to 53.
There are 54 GPIOs (0-53) in total. Only some of them are available for general use on the GPIO header, the rest are used for internal functions.

0 and 1 are used for the HAT ID pins. (i2c bus 0 on pins 27 and 28).

dharanivel
Posts: 33
Joined: Sun Dec 16, 2018 4:36 am

Re: How to find the address of gpio in raspberry pi zero

Fri Dec 21, 2018 3:53 pm

thankyou very much, how can i use gpio as input and pwm output in arm assrmbly language.

LdB
Posts: 1325
Joined: Wed Dec 07, 2016 2:29 pm

Re: How to find the address of gpio in raspberry pi zero

Fri Dec 21, 2018 4:52 pm

To read gpio, set the pin to input mode and read the bit in the read register you get a 0 or 1
BCM2835.PDF Manual Section 6 ... Pin function set registers GPFSEL, Read level registers GPLEV

For PWM you set a pin with the PWM capability to that mode. You then write data to the PWM register or via the DMA.
BCM2835.PDF Manual Section 9

It really isn't possible to help you much beyond that because they have changed this forum section are you doing it under linux or baremetal?
For the PWN are you trying to output it to an external peripheral or send to the audio output?

In general I would suggest you do a minimal processor bootstub in assembler and work in C it is a lot easier and there are far more samples around.

C compiler spit of assembler code for setup_gpio function, entry R0 = GPIO pin number (0-53 valid), R1 = mode

Code: Select all

gpio_setup:
        cmp     r0, #53
        cmpls   r1, #7
        mov     r3, r0
        movls   r0, #1
        movhi   r0, #0
        bxhi    lr
        push    {r4, r5, r6, lr}
        mov     r6, #7
        ldr     r4, .L11
        umull   r4, r5, r3, r4
        lsr     r4, r5, #3
        lsl     lr, r4, #2
        add     ip, lr, #1056964608
        add     ip, ip, #2097152
        add     lr, lr, r4
        ldr     r2, [ip]
        sub     r3, r3, lr, lsl #1
        add     r3, r3, r3, lsl #1
        bic     r2, r2, r6, lsl r3
        orr     r3, r2, r1, lsl r3
        str     r3, [ip]
        pop     {r4, r5, r6, pc}
.L11:
        .word   -858993459 
C compiler spit of assembler code for gpio_input function, entry R0 = GPIO pin number (0-53 valid), R0 returns 0 or 1

Code: Select all

gpio_input:
        cmp     r0, #53
        bhi     .L15
        mov     r1, #1
        lsr     r2, r0, #5
        ldr     r3, .L16
        lsl     r2, r2, #2
        add     r3, r2, r3
        ldr     r3, [r3, #4]
        and     r0, r0, #31
        ands    r3, r3, r1, lsl r0
        movne   r0, r1
        moveq   r0, #0
        bx      lr
.L15:
        mov     r0, #0
        bx      lr
.L16:
        .word   1059061808
Original C code

Code: Select all

#include <stdbool.h>
#include <stdint.h>

#define MAX_GPIO_NUM 54

typedef enum {
	GPIO_INPUT = 0b000,		// 0
	GPIO_OUTPUT = 0b001,		// 1
	GPIO_ALTFUNC5 = 0b010,		// 2
	GPIO_ALTFUNC4 = 0b011,		// 3
	GPIO_ALTFUNC0 = 0b100,		// 4
	GPIO_ALTFUNC1 = 0b101,		// 5
	GPIO_ALTFUNC2 = 0b110,		// 6
	GPIO_ALTFUNC3 = 0b111,		// 7
} GPIOMODE;

/*--------------------------------------------------------------------------}
{    RASPBERRY PI GPIO HARDWARE REGISTERS - BCM2835.PDF Manual Section 6	}
{--------------------------------------------------------------------------*/
struct __attribute__((__packed__, aligned(4))) GPIORegisters {
	uint32_t GPFSEL[6];			// 0x00  GPFSEL0 - GPFSEL5
	uint32_t reserved1;			// 0x18  reserved
	uint32_t GPSET[2];			// 0x1C  GPSET0 - GPSET1;
	uint32_t reserved2;			// 0x24  reserved
	uint32_t GPCLR[2];			// 0x28  GPCLR0 - GPCLR1
	uint32_t reserved3;			// 0x30  reserved
	const uint32_t GPLEV[2];		// 0x34  GPLEV0 - GPLEV1   ** Read only hence const
	uint32_t reserved4;			// 0x3C  reserved
	uint32_t GPEDS[2];			// 0x40  GPEDS0 - GPEDS1 
	uint32_t reserved5;			// 0x48  reserved
	uint32_t GPREN[2];			// 0x4C  GPREN0 - GPREN1;	 
	uint32_t reserved6;			// 0x54  reserved
	uint32_t GPFEN[2];			// 0x58  GPFEN0 - GPFEN1;
	uint32_t reserved7;			// 0x60  reserved
	uint32_t GPHEN[2];			// 0x64  GPHEN0 - GPHEN1;
	uint32_t reserved8;			// 0x6c  reserved
	uint32_t GPLEN[2];			// 0x70  GPLEN0 - GPLEN1;
	uint32_t reserved9;			// 0x78  reserved
	uint32_t GPAREN[2];			// 0x7C  GPAREN0 - GPAREN1;
	uint32_t reserved10;			// 0x84  reserved
	uint32_t GPAFEN[2]; 			// 0x88  GPAFEN0 - GPAFEN1;
	uint32_t reserved11;			// 0x90  reserved
	uint32_t GPPUD; 				// 0x94  GPPUD 
	uint32_t GPPUDCLK[2]; 		// 0x98  GPPUDCLK0 - GPPUDCLK1;
};

#define RPi_IO_Base_Addr 0x3F000000
#define GPIO ((volatile __attribute__((aligned(4))) struct GPIORegisters*)(uintptr_t)(RPi_IO_Base_Addr + 0x200000))
bool gpio_setup (const unsigned int gpio, const GPIOMODE mode) 
{
	if ((gpio < MAX_GPIO_NUM) && (mode >= 0)  && (mode <= GPIO_ALTFUNC3))// Check GPIO pin number and mode valid
	{
		uint32_t bit = ((gpio % 10) * 3);				// Create bit mask
		uint32_t mem = GPIO->GPFSEL[gpio / 10];	// Read register
		mem &= ~(7 << bit);						// Clear GPIO mode bits for that port
		mem |= (mode << bit);					// Logical OR GPIO mode bits
		GPIO->GPFSEL[gpio / 10] = mem;			// Write value to register
		return true;								// Return true
	}
	return false;									// Return false is something is invalid
}

bool gpio_input (const unsigned int gpio) 
{
	if (gpio < MAX_GPIO_NUM)					// Check GPIO pin number valid
	{
		uint32_t bit = 1 << (gpio % 32);				// Create mask bit
		uint32_t mem = GPIO->GPLEV[gpio / 32];	// Read port level
		if (mem & bit) return true;					// Return true if bit set
	}
	return false;									// Return false
}

Return to “Bare metal, Assembly language”