nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Setting the output register for a GPIO on Pi 4

Thu Sep 26, 2019 1:06 am

Hello,

I am newbie to the raspberry pi world and I am trying to learn how can I build some bare metal programs on a raspberry pi.

I have a raspberry pi 4 model b and I am trying to change the output register value for a specific GPIO. I tried finding the address of the GPIO but not able to find the right address.

Would anyone have any resources like the BCM2835 PDF which defines those register views? Or any other information like how can I find those addresses manually?

My sample code:

Code: Select all

mov  r0,     #0xF0000000
orr  r0, r0, #0x02000000
orr  r0, r0, #0x00020000
orr  r0, r0, #0x00000008
mov  r1, #1
str  r1, [r0]

mov     r0, #0xF0000000
orr     r0, r0, #0x00200000
orr     r0, r0, #0x0000001c
mov     r1, #1
lsl     r1, r1, #20
str     r1, [r0]
 
loop:
b loop

nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Re: Setting the output register for a GPIO on Pi 4

Thu Sep 26, 2019 8:40 am

Small update on this: the code is working, I was trying to target GPIO 20 pin but this is working with pins 2, 3 and 4. The voltage is high at 2 and dropping to a low-value on pin 4.

Would anyone be able to suggest what would be the right MMIO for GPIO 20 and what would be the process to calculate that?

nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Re: Setting the output register for a GPIO on Pi 4

Thu Sep 26, 2019 11:36 pm

I updated the code as some threads on the forum suggested that the peripheral memory base address has been updated to 0xFE000000. It still doesn't seem to work.

Trying to switch on the LED on pin 16

Code: Select all

mov r0, #0xF0000000
orr r0, #0x0E000000
orr r0, #0x00200000
orr r0, #0x00000004
mov r1, #1
lsl r1, #18
str r1, [r0]

mov r0, #0xF0000000
orr r0, #0x0E000000
orr r0, #0x00200000
orr r0, #0x0000001C
mov r1, #1
lsl r1, #16
str r1, [r0]
loop$:
b loop$

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

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 3:46 am

You completely override whatever is on GPFSEL1 .. surely you want to read it mask off the 3 bits and write the function for the pin you are trying to change.

At a guess something like this seems more appropriate

Code: Select all

mov r1, #1
mov r2, #7
lsl r1, #18
lsl r2, #18
ldr r3, [r0]
bic r3, r3, r2
orr r3, r3, r1
str r3, [r0]
You also talk about Pin 16 ... Pin 16 is NOT GPIO16

GPIO16 is pin 10 on the 40 pin header.

So can we stick to GPIO number please we aren't interested in pin number from a programming point of view.

nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 9:54 am

LdB wrote:
Fri Sep 27, 2019 3:46 am
You completely override whatever is on GPFSEL1 .. surely you want to read it mask off the 3 bits and write the function for the pin you are trying to change.

At a guess something like this seems more appropriate

Code: Select all

mov r1, #1
mov r2, #7
lsl r1, #18
lsl r2, #18
ldr r3, [r0]
bic r3, r3, r2
orr r3, r3, r1
str r3, [r0]
You also talk about Pin 16 ... Pin 16 is NOT GPIO16

GPIO16 is pin 10 on the 40 pin header.

So can we stick to GPIO number please we aren't interested in pin number from a programming point of view.
Apologies for not being clear about the Pin number. I was referring to the GPIO pin and not the Pin 16. To understand this well, you state that GPIO16 is pin 10 on the 40 pin header, how did you make that connection? I could not make that connection based on all the reading I have done. Do you any specific resource you would recommend to learn this?

I understand that I was trying to override the entire GPFSEL1. This was the first time I was writing assembly code hence took this path. Your code certainly seems a lot more appropriate than mine.

I tried your code but it did not light up the LED. I am unsure how should I debug this element and understand at what stage am I going wrong. I do not know if the code has any bugs or I am referring to the wrong pin when creating the circuit or it is something else. Would you have any ideas how about I can go about debugging this?

Btw, I have been following the Baking Pi tutorial on this link - https://www.cl.cam.ac.uk/projects/raspb ... /ok01.html

Thank you for your response and willingness to help.

User avatar
Burngate
Posts: 6100
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK Tralfamadore
Contact: Website

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 10:01 am

nickell8448 wrote:
Fri Sep 27, 2019 9:54 am
To understand this well, you state that GPIO16 is pin 10 on the 40 pin header, how did you make that connection? I could not make that connection based on all the reading I have done. Do you any specific resource you would recommend to learn this?
https://pinout.xyz/#

nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 10:11 am

Burngate wrote:
Fri Sep 27, 2019 10:01 am
nickell8448 wrote:
Fri Sep 27, 2019 9:54 am
To understand this well, you state that GPIO16 is pin 10 on the 40 pin header, how did you make that connection? I could not make that connection based on all the reading I have done. Do you any specific resource you would recommend to learn this?
https://pinout.xyz/#
Thanks for your response Burngate. As far as I understood this was that Pin 10 = BCM 15 and Pin 36 = BCM 16. I am not sure how pin 10 = GPIO 16.

Hope my question makes sense.

User avatar
Burngate
Posts: 6100
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK Tralfamadore
Contact: Website

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 5:20 pm

Once upon a time ... when the first Pi was being designed, on the chip they wanted to use they had a range of GPIOs (General Purpose Input/Outputs) that they wanted to bring out to a header.

Inside the chip, the registers that accessed them had them in a certain order.
This gave rise to the GPIO numbering system, otherwise known as BCM numbering (Broadcom designed and made the chip)

However, it just so happened that (because of, partly, the way they appeared at the bottom of the chip) it was easiest to put them in a different order on the header.
Hence the Header-pin numbers

And along came a guy who decided to simplify the numbering, by inventing the WiringPi numbers.

Most software can cope with whichever numbering system you want to use, but since we're in the bare-metal subforum, you'll have to ensure your software can cope with what You do.

It's probably easiest to refer to the BCM numbers, but you could, if you so desired, invent a whole new system.
Your software could call GPIO 2 (header pin 3) Alef-Bet and GPIO 3 (header pin 5) Alef-Gimel. Or perhaps SDA1 and SCL1.

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

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 5:37 pm

nickell8448 wrote:
Fri Sep 27, 2019 10:11 am
Thanks for your response Burngate. As far as I understood this was that Pin 10 = BCM 15 and Pin 36 = BCM 16. I am not sure how pin 10 = GPIO 16.
You are correct and I should use my glasses when reading datasheets :-)

Pin 36 = GPIO 16

Regardless stick to BCM or GPIO numbers we aren't interested in pin numbers for programming it get to confusing otherwise.

nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 9:36 pm

Burngate wrote:
Fri Sep 27, 2019 5:20 pm
Once upon a time ... when the first Pi was being designed, on the chip they wanted to use they had a range of GPIOs (General Purpose Input/Outputs) that they wanted to bring out to a header.

Inside the chip, the registers that accessed them had them in a certain order.
This gave rise to the GPIO numbering system, otherwise known as BCM numbering (Broadcom designed and made the chip)

However, it just so happened that (because of, partly, the way they appeared at the bottom of the chip) it was easiest to put them in a different order on the header.
Hence the Header-pin numbers

And along came a guy who decided to simplify the numbering, by inventing the WiringPi numbers.

Most software can cope with whichever numbering system you want to use, but since we're in the bare-metal subforum, you'll have to ensure your software can cope with what You do.

It's probably easiest to refer to the BCM numbers, but you could, if you so desired, invent a whole new system.
Your software could call GPIO 2 (header pin 3) Alef-Bet and GPIO 3 (header pin 5) Alef-Gimel. Or perhaps SDA1 and SCL1.
Thanks for explanation Burngate. I think I will refer to the BCM numbers rather than inventing a new system myself :)

nickell8448
Posts: 7
Joined: Thu Sep 26, 2019 12:57 am

Re: Setting the output register for a GPIO on Pi 4

Fri Sep 27, 2019 9:40 pm

LdB wrote:
Fri Sep 27, 2019 5:37 pm
nickell8448 wrote:
Fri Sep 27, 2019 10:11 am
Thanks for your response Burngate. As far as I understood this was that Pin 10 = BCM 15 and Pin 36 = BCM 16. I am not sure how pin 10 = GPIO 16.
You are correct and I should use my glasses when reading datasheets :-)

Pin 36 = GPIO 16

Regardless stick to BCM or GPIO numbers we aren't interested in pin numbers for programming it get to confusing otherwise.
I will stick to the BCM or GPIO numbers.

I have not been able to get the thing running. I installed Noobs OS on a different SD card and wrote a python script to work on the LED and that worked well.

Would you have any tips about how to debug this issue?

User avatar
Burngate
Posts: 6100
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK Tralfamadore
Contact: Website

Re: Setting the output register for a GPIO on Pi 4

Sat Sep 28, 2019 8:54 am

Having read LdB's reply to your question, and realised I'd misread your question (I too can't tell the difference between 10 and 36) I came downstairs this morning ready to delete my reply as totally irrelevant.
However, since you've quoted me, I'll leave it there, as a lesson for others: read the question properly before replying!

Aran
Posts: 36
Joined: Fri Jan 25, 2019 5:55 pm

Re: Setting the output register for a GPIO on Pi 4

Sat Sep 28, 2019 2:01 pm

Hello,
by retrieving the various information on the Internet, I made a complete table of the J8 Pinout (40-pin Header) and corresponding GPIO functions with the Pi 4, below :

Image

You can find some explanations for programming the GPIO here.

I also had fun lighting the LED ACT. For that I use the mailbox and GPIO Virtual Buffer. Here is the code :

Code: Select all

struc MboxGetGPIOVirtualBuffer
{
	dw .end - $			; message size
	dw $00000000			; request code

	dw Get_GPIO_Virtual_Buffer	; tag identifier 0x40010
	dw 0x00000004			; buffer size in bytes
	dw 0x00000000			; process request
	dw 0				; response value buffer

	dw 0x00000000			; end tag
	.end:
}

	align 16
	mboxGetGPIOVirtualBuffer	MboxGetGPIOVirtualBuffer
	
	mov r0,MAIL_TAGS		; mailbox channel 8
	mov r1,mboxGetGPIOVirtualBuffer	; message address
	bl mboxCall
	
	mov r1,mboxGetGPIOVirtualBuffer
	ldr r0,[r1,20]			; read the GPIO Virtual Buffer address
	and r0,0x3fffffff		; conversion to physical address
	
	ldr r1,[r0]
	orr r1,0x00010000		; update of the led status to ON
	str r1,[r0]
I wrote a post about the mailbox programming here : https://spider-os.com/commentaires.php? ... 12#mailbox

manson1972
Posts: 2
Joined: Fri Aug 16, 2019 3:00 pm

Re: Setting the output register for a GPIO on Pi 4

Tue Oct 01, 2019 6:20 pm

Hello, I've been following your SpiderOS site, as I am trying to learn a few things.

One question I have is regarding this:

"I also had fun lighting the LED ACT. For that I use the mailbox and GPIO Virtual Buffer"

How did you find out that you had to use the mailbox the GPIO Virtual buffer to light the LED ACT?

Aran
Posts: 36
Joined: Fri Jan 25, 2019 5:55 pm

Re: Setting the output register for a GPIO on Pi 4

Wed Oct 02, 2019 7:34 pm

As they say : Google is your friend ;-)

I had already written the code to turn on the ACT led on a Raspberry Pi 2, but it did not work with the Pi3. Which led me to do some research on the Internet. One of the explanations is the change of GPIO for the LED.

But ultimately by analyzing my old code I managed to make it work with the Pi 4 and without using the Mailbox.
On the Pi 4 the ACT LED is on the GPIO42 (not present on the pins). To turn on the LED, you have to program this GPIO42 in output, and set GPIO in the GPSET register. Here is the code :

Code: Select all

PERIPHERAL_BASE		= 0xfe000000	; Pi 4
GPIO_BASE		= 0x00200000
GPIO_GPFSEL4		= 0x10		; GPIO Function Select 4
GPIO_FSEL2_OUT		= 0x40		; FSEL42 output
GPIO_GPSET1		= 0X20		; GPIO Pin Output Set 1

imm32 r4,PERIPHERAL_BASE + GPIO_BASE
  
ldr r0,[r4,GPIO_GPFSEL4]
bic r0,0x1c0			; clear bits 8-6
orr r0,GPIO_FSEL2_OUT		; GPIO 42 in output
str r0,[r4,GPIO_GPFSEL4]	

mov r0,1 SHL 10			; bit 42 = 1 (set GPIO 42)
str r0,[r4,GPIO_GPSET1]		; light up the led

manson1972
Posts: 2
Joined: Fri Aug 16, 2019 3:00 pm

Re: Setting the output register for a GPIO on Pi 4

Thu Oct 03, 2019 5:52 pm

Yes, I googled a lot, and found a lot of people saying "use the mailbox" but nowhere did I find where that information originally came from. I was wondering why it wasn't done like you just showed could be done. Guess now I know :)

Thanks!

zhak
Posts: 13
Joined: Wed Jul 03, 2019 5:18 pm

Re: Setting the output register for a GPIO on Pi 4

Sun Oct 06, 2019 9:21 pm

Unfortunately I'm unable to turn on the LED connected to any 40-pin output :(

Code: Select all

processor cpu64_v8
code64

_start:
        mrs x10, mpidr_el1
        and x10, x10, 0xff
        cbnz x10, halt
        adr x11, _start
        adr x12, kernel
        mov sp, x11
        blr x12
halt:   wfe
        b halt

kernel:
        mov x4, 0xfe200000  ; turn on ACT LED (GPIO 42)
        ldr x0, [x4, 0x10]
        bic x0, x0, 0x1c0
        orr x0, x0, 0x40
        str x0, [x4, 0x10]  
        mov x0, 1 shl 10
        str x0, [x4, 0x20]

        ldr x0, [x4, 0x04]  ; turn on LED on GPIO 14 (Pin 8)
        bic x0, x0, 0x7000
        orr x0, x0, 0x1000
        str x0, [x4, 0x04]
        mov x0, 1 shl 14
        str x0, [x4, 0x1c]

here:   b here
        ret
        
ACT LED turns on, but LED connected to physical pin 8 (GPIO14) doesn't work. It flashes for a second during boot (I assume because of its default configuration as TX1). Then ACT LED turn on and GPIO14 led turns off

What am I doing wrong? (I already tried clearing both GPIO14 and 15, and also tried writing to GPCLR0 instead of GPSET0 -- no result)

Aran
Posts: 36
Joined: Fri Jan 25, 2019 5:55 pm

Re: Setting the output register for a GPIO on Pi 4

Sun Oct 06, 2019 10:27 pm

Hello Zhak,
your code seems correct. Maybe it is necessary to update the GPSET register, instead of overwriting it (so as not to change the status of others GPIOs) :

Code: Select all

	; turn on LED on GPIO 14 (Pin 8)
        mov x4, 0xfe200000
        ldr x0, [x4, 0x04]	; GPIO Function Select 1
        bic x0, x0, 0x7000	; clear FSEL14
        orr x0, x0, 0x1000	; FSEL14 = 001b = GPIO 14 in output
        str x0, [x4, 0x04]
        ldr x0, [x4, 0x1c]	; GPIO Pin Output Set 0
        orr x0, x0, 1 shl 14	; set GPIO14
        str x0, [x4, 0x1c]
        
I just read the documentation on page 95, which indicates that writing a 0 has no effect. So it must be something else.

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

Re: Setting the output register for a GPIO on Pi 4

Mon Oct 07, 2019 1:13 am

@zhak are you sure the cores aren't just sent to hang because you are playing a very dangerous game.
In the MPIDR_EL1 register bits[1:0] = CPU ID, bits [7:2] are Reserved on the CortexA72.
Your code AND the register value to 0xFF and if none zero hang the core.
So any bit set in those reserved bits and you hang core 0.
Ir really needs to AND against 0x3

zhak
Posts: 13
Joined: Wed Jul 03, 2019 5:18 pm

Re: Setting the output register for a GPIO on Pi 4

Mon Oct 07, 2019 9:14 am

Hmm, I used Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile as a reference.
Section D13.2.88 states Bits[0..7] in MPIDR_EL1 register are Affinity level 0.

And Section D7.4:
- In an implementation containing multiple PEs, each PE is identified by a unique affinity value reported by MPIDR_EL1{Aff3, Aff2, Aff1, Aff0}, where the value of affinity level 0 is the most significant for determining the PE behavior, and the values of higher affinity levels are less significant. Affinity level 3 is only supported in AArch64 state.
- An implementation is described as multithreaded when the lowest level of affinity consists of logical PEs that are implemented using a multithreading type approach...
Anyway, checking either 2 or 8 bits has the same result. I'm thinking that maybe switching from Alt0 to Output occurs too fast and some delay is required. Could this be an issue?

Side question: are .dtb files used by firmware for system configuration or they are used only by Linux as a reference?

zhak
Posts: 13
Joined: Wed Jul 03, 2019 5:18 pm

Re: Setting the output register for a GPIO on Pi 4

Mon Oct 07, 2019 11:10 am

I'm dumb. I spent all day yesterday trying to figure out what's wrong... the problem was storing 64 bits to 32-bit register. should have used W registers instead of X

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

Re: Setting the output register for a GPIO on Pi 4

Mon Oct 07, 2019 11:53 am

Glad you found problem, but just for completeness

Check the actual manual CortexA72 manual it is very specific ... Table 4-17 MPIDR_EL1 bit assignments
http://infocenter.arm.com/help/index.js ... 49036.html

Return to “Bare metal, Assembly language”