~ruther/qmk_firmware

b6316c502499fd245cfb5ad468d7870d229f55d4 — Joel Challis 5 years ago fc4ef69
[Keymap] I2C scanner (#8454)

* Add i2c scanner keymap

* Add bodge for chibios

* Fix readme title

* make chibios bodge a little cleaner

* fix typo in readme
A keyboards/handwired/onekey/keymaps/i2c_scanner/config.h => keyboards/handwired/onekey/keymaps/i2c_scanner/config.h +6 -0
@@ 0,0 1,6 @@
#pragma once

// AVR: can change to other supported values
#define F_SCL 100000UL

// TODO: add some default ARM configs for i2cv1 and i2cv2

A keyboards/handwired/onekey/keymaps/i2c_scanner/keymap.c => keyboards/handwired/onekey/keymaps/i2c_scanner/keymap.c +66 -0
@@ 0,0 1,66 @@
#include QMK_KEYBOARD_H

#include "i2c_master.h"
#include "debug.h"

#define TIMEOUT 50

// TODO: remove patch
#ifdef PROTOCOL_CHIBIOS
#    pragma message("ChibiOS is currently 'best effort' and might not report accurate results")

i2c_status_t i2c_start_bodge(uint8_t address, uint16_t timeout) {
    i2c_start(address);

    // except on ChibiOS where the only way is do do "something"
    uint8_t data = 0;
    return i2c_readReg(address, 0, &data, sizeof(data), TIMEOUT);
}

#    define i2c_start i2c_start_bodge
#endif

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    LAYOUT(KC_A)  //
};

void do_scan(void) {
    uint8_t nDevices = 0;

    dprintf("Scanning...\n");

    for (uint8_t address = 1; address < 127; address++) {
        // The i2c_scanner uses the return value of
        // i2c_start to see if a device did acknowledge to the address.
        i2c_status_t error = i2c_start(address << 1, TIMEOUT);
        if (error == I2C_STATUS_SUCCESS) {
            i2c_stop();
            dprintf("  I2C device found at address 0x%02X\n", address);
            nDevices++;
        } else {
            // dprintf("  Unknown error (%u) at address 0x%02X\n", error, address);
        }
    }

    if (nDevices == 0)
        dprintf("No I2C devices found\n");
    else
        dprintf("done\n");
}

uint16_t scan_timer = 0;

void matrix_scan_user(void) {
    if (timer_elapsed(scan_timer) > 5000) {
        do_scan();
        scan_timer = timer_read();
    }
}

void keyboard_post_init_user(void) {
    debug_enable = true;
    debug_matrix = true;

    i2c_init();
    scan_timer = timer_read();
}

A keyboards/handwired/onekey/keymaps/i2c_scanner/readme.md => keyboards/handwired/onekey/keymaps/i2c_scanner/readme.md +36 -0
@@ 0,0 1,36 @@
# i2c_scanner

Aiming to provide a more qmk friendly version of <https://playground.arduino.cc/Main/I2cScanner/>

> This very simple ~~sketch~~ keymap scans the I2C-bus for devices. If a device is found, it is reported to the ~~Arduino serial monitor~~ console.


## Flashing

Pick a target that is aligned to the MCU you want to test:

```console
make handwired/onekey/elite_c:i2c_scanner:flash # also 32u4 + dfu bootloader
make handwired/onekey/promicro:i2c_scanner:flash
make handwired/onekey/teensy_2:i2c_scanner:flash

# ChibiOS is currently 'best effort' and might not report accurate results
make handwired/onekey/proton_c:i2c_scanner:flash
```

others might work with additional configuration.

## Usage

Output is viewable through a compatible tool <https://docs.qmk.fm/#/newbs_testing_debugging?id=debugging-tools>.

You can change the wires, and plug-in I2C devices while the i2c_scanner is running.

The output of the console will look like this:

```
Listening:
Scanning...
  I2C device found at address 0x20
done
```

A keyboards/handwired/onekey/keymaps/i2c_scanner/rules.mk => keyboards/handwired/onekey/keymaps/i2c_scanner/rules.mk +3 -0
@@ 0,0 1,3 @@
CONSOLE_ENABLE = yes

QUANTUM_LIB_SRC += i2c_master.c