Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Experimenting with inlined bit-band access functions

  1. #1
    Senior Member
    Join Date
    Mar 2017
    Location
    Oakland, CA, USA
    Posts
    169

    Experimenting with inlined bit-band access functions

    Inspired by `digitalReadFast` and `digitalWriteFast` and how they can compile to just one instruction, I wanted to see if it was possible to access and change the bit-band memory regions using code that also compiles to just a few instructions, and without using #defines. Hooray for modern C++ features!

    Example use:
    Code:
    // 8-bit
    setGPIOBit(&UART0_C2, UART_C2_TE);
    clearGPIOBit(&UART0_C2, UART_C2_TE);
    if (readGPIOBit(&UART0_C2, UART_C2_TE)) {
      // Stuff
    }
    
    // 32-bit
    setGPIOBit(&LPUART0_CTRL, LPUART_CTRL_TE);
    clearGPIOBit(&LPUART0_CTRL, LPUART_CTRL_TE);
    if (readGPIOBit(&LPUART0_CTRL, LPUART_CTRL_TE)) {
      // Stuff
    }
    I've attached the current version of the code and a `main` file so you can see how it compiles. Compile with the `-S` option to see the assembly. I use PlatformIO. Unfortunately, this forum claims `.ini` files are "invalid", so here's the `platformio.ini` contents:
    Code:
    [common]
    build_flags = -Wall -S
    monitor_speed = 115200
    
    [env:teensy36]
    platform = teensy
    board = teensy36
    framework = arduino
    build_flags = ${common.build_flags}
    monitor_speed = ${common.monitor_speed}
    If you run into trouble or find that the code doesn't actually compile into just a few instructions, it's possible your build system is different than what I'm using. When I resurrected this today, I experimented with minimizing the source and it still worked for me. When I started playing with this last year, I found that there were some other changes I had to make to get it to work. These included using only `uint32_t` bit masks and using a `switch` statement instead of the array access in `countTrailingZeros`. I also found that I had to have two `countTrailingZeros` versions, one for 8-bit and one for 32-bit. Even then, I was having some difficulty. But in any case, it works today using the latest PlatformIO Teensy tools (1.148.0).

    The sources:
    bitband_routines.h
    bitband_main.cpp

  2. #2
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    728
    Nice, I did a similar exercise a couple of years ago. .https://github.com/luni64/pins Quite amazing what can be done with modern c++ :-)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •