Hi, folks,

I have been trying to bit bang an interface on the GPIO pins.  I looked at 
a bunch of the tutorials on the web and managed to build something that 
worked.  However, the speed seems to be a bit slower than I would expect.

My scope shows that I am running at about 2.95MHz (It also roughly matches 
the result from here--http://chiragnagpal.com/examples.html of 2.78MHz). 
 That seems slow--I would have expected closer to 25MHz--so I think I'm an 
order of magnitude off somewhere  The assembly code seems to be as 
expected, so my question is:

What is slowing things down?

Since the assembly is basically ldr/str in a chain, something must be 
stalling the pipeline, but I don't know what.

Suggestions would be appreciated.

I'm running Debian Jessie Linux arm 4.1.6-ti-r11 #1 SMP PREEMPT Tue Aug 18 
21:36:11 UTC 2015 armv7l GNU/Linux

Thanks.


The assembly code looks optimal at 4 instructions per toggle (I'm using 
clang):
        .loc    2 80 2                  @ gpi.c:80:2
        ldr     r1, [sp, #28]
        str     r0, [r1]
        .loc    2 81 9                  @ gpi.c:81:9
        ldr     r1, [sp, #32]
        str     r0, [r1]
        .loc    2 82 2                  @ gpi.c:82:2
        ldr     r1, [sp, #28]
        str     r0, [r1]
        .loc    2 83 9                  @ gpi.c:83:9
        ldr     r1, [sp, #32]
        str     r0, [r1]



The C Code I used to toggle the pin P9_23 (GPIO1_17):


#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> 

#include <unistd.h>
#include <assert.h>

#define GPIO_OE 0x134
#define GPIO_SETDATAOUT 0x194
#define GPIO_CLEARDATAOUT 0x190


// Hunt these addresses down from ls -al /sys/devices/platform/ocp | grep 
gpio
// You can also pull them from the TI manual (spruh73l.pdf)
#define GPIO0_BASE 0x44E07000
#define GPIO1_BASE 0x4804C000
#define GPIO2_BASE 0x481AC000
#define GPIO3_BASE 0x481AE000

#define GPIO_SIZE  0x00001000


#define PIN_17 ((uint32_t)1<<17)


uint32_t ui32Base[] = {GPIO0_BASE, GPIO1_BASE, GPIO2_BASE, GPIO3_BASE};
uint8_t volatile * bbGPIOMap[] = {0, 0, 0, 0};


int main(int argc, char *argv[])
{
    unsigned int ui;
    
    uint32_t volatile * gpio_oe_addr = NULL;
    uint32_t volatile * gpio_setdataout_addr = NULL;
    uint32_t volatile * gpio_cleardataout_addr = NULL;

    
    int fd = open("/dev/mem", O_RDWR);

    for(ui=0; ui<4; ++ui) {
bbGPIOMap[ui] = mmap(0, GPIO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 
ui32Base[ui]);
assert(bbGPIOMap[ui] != MAP_FAILED);
    }

    
    gpio_oe_addr = (uint32_t volatile *)(bbGPIOMap[1] + GPIO_OE);
    gpio_setdataout_addr = (uint32_t volatile *)(bbGPIOMap[1] + 
GPIO_SETDATAOUT);
    gpio_cleardataout_addr = (uint32_t volatile *)(bbGPIOMap[1] + 
GPIO_CLEARDATAOUT);



    *gpio_oe_addr = *gpio_oe_addr & ~PIN_17;
    
    while(1) {
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
        *gpio_setdataout_addr = PIN_17;
*gpio_cleardataout_addr = PIN_17;
    }
    
    //*(uint32_t volatile *)(bbGPIOMap[3] + GPIO_SETDATAOUT) = (uint32_t)1 
<< 14;
    //*(uint32_t volatile *)(bbGPIOMap[3] + GPIO_CLEARDATAOUT) = 
(uint32_t)1 << 14;

    close(fd);
    return 0;
}



-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to beagleboard+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to