Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4930

Bare metal, Assembly language • set gpio pin function is assembly

$
0
0
I open /dev/gpiomem and mmap it to application memory. I set a gpio pin to be an output with

Code:

// Calling sequence://      x0 <- address of GPIO in mapped memory//      w1 <- GPIO pin number//      w2 <- pin function// Constants for assembler        .equ    FIELD_MASK, 0b111  // 3 bits// Code        .text        .align  2        .global gpio_pin_function        .type   gpio_pin_function, %functiongpio_pin_function:// Determine register and location of pin function field        mov     w3, 10          // ten fields per GPFSEL register        udiv    w4, w1, w3      // w4 = GPFSEL register number        msub    w5, w4, w3, w1  // pin field number in register// Compute address of GPFSEL register and pin field in register             lsl     w4, w4, 2       // w4 = offset to GPSEL register        add     x0, x0, x4      // GPFSELn memory address        ldr     w4, [x0]        // w4 = GPFSELn register contents        add     w5, w5, w5, lsl 1   // 3 X pin field number        mov     w6, FIELD_MASK  // gpio pin field        lsl     w6, w6, w5      // shift to field bit position        bic     w4, w4, w6      // clear current pin field        lsl     w2, w2, w5      // shift function code to pin position        orr     w4, w4, w2      // insert function code        str     w4, [x0]        // update register        ret
When I look at the memory for GPFSEL0 in gdb, it's 0x6770696f, but when I load that into w4 it's 0. And after I orr the function code with the value in w4, and then store the result back in memory, the value in memory doesn't change.

I realize that the mapped memory isn't really memory, but an i/o port. But my question is, do I need to load the 32 bits in GPFSEL0, orr in the three bits that set the function of my pin, and then store the result back? The BCM2835 documentation seems to imply that this is the way to do it. It says that if I store 0 in the other 3-bit fields, they will become inputs.

I also tried setting a second pin to be an output with another call to this function. When I looked with gdb, the mapped memory location that the 3-bit field corresponding to the first pin had been changed to 000, making it an input.

I know that there are separate set and clr gpio registers to avoid loading the current value, changing it, and storing it back. Storing a 0 in the bits of those registers has no effect.

I also realize that i/o is more complex that what I'm doing. I just want to give students a general idea of how i/o works by using the gpio to blink an led. This is for an introductory course. They're not ready for the full story, but I also don't want to lie to them.

Statistics: Posted by rplantz — Thu Dec 14, 2023 10:06 pm



Viewing all articles
Browse latest Browse all 4930

Trending Articles