qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

pca9555.c (2632B)


      1 // Copyright 2020 zvecr<git@zvecr.com>
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #include "i2c_master.h"
      5 #include "pca9555.h"
      6 
      7 #include "debug.h"
      8 
      9 #define SLAVE_TO_ADDR(n) (n << 1)
     10 #define TIMEOUT 100
     11 
     12 enum {
     13     CMD_INPUT_0 = 0,
     14     CMD_INPUT_1,
     15     CMD_OUTPUT_0,
     16     CMD_OUTPUT_1,
     17     CMD_INVERSION_0,
     18     CMD_INVERSION_1,
     19     CMD_CONFIG_0,
     20     CMD_CONFIG_1,
     21 };
     22 
     23 void pca9555_init(uint8_t slave_addr) {
     24     static uint8_t s_init = 0;
     25     if (!s_init) {
     26         i2c_init();
     27 
     28         s_init = 1;
     29     }
     30 
     31     // TODO: could check device connected
     32 }
     33 
     34 bool pca9555_set_config(uint8_t slave_addr, pca9555_port_t port, uint8_t conf) {
     35     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
     36     uint8_t cmd  = port ? CMD_CONFIG_1 : CMD_CONFIG_0;
     37 
     38     i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
     39     if (ret != I2C_STATUS_SUCCESS) {
     40         print("pca9555_set_config::FAILED\n");
     41         return false;
     42     }
     43 
     44     return true;
     45 }
     46 
     47 bool pca9555_set_output(uint8_t slave_addr, pca9555_port_t port, uint8_t conf) {
     48     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
     49     uint8_t cmd  = port ? CMD_OUTPUT_1 : CMD_OUTPUT_0;
     50 
     51     i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
     52     if (ret != I2C_STATUS_SUCCESS) {
     53         print("pca9555_set_output::FAILED\n");
     54         return false;
     55     }
     56 
     57     return true;
     58 }
     59 
     60 bool pca9555_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB) {
     61     uint8_t addr    = SLAVE_TO_ADDR(slave_addr);
     62     uint8_t conf[2] = {confA, confB};
     63 
     64     i2c_status_t ret = i2c_write_register(addr, CMD_OUTPUT_0, &conf[0], sizeof(conf), TIMEOUT);
     65     if (ret != I2C_STATUS_SUCCESS) {
     66         dprintf("pca9555_set_output::FAILED::%u\n", ret);
     67         return false;
     68     }
     69 
     70     return true;
     71 }
     72 
     73 bool pca9555_read_pins(uint8_t slave_addr, pca9555_port_t port, uint8_t* out) {
     74     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
     75     uint8_t cmd  = port ? CMD_INPUT_1 : CMD_INPUT_0;
     76 
     77     i2c_status_t ret = i2c_read_register(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
     78     if (ret != I2C_STATUS_SUCCESS) {
     79         print("pca9555_read_pins::FAILED\n");
     80         return false;
     81     }
     82 
     83     return true;
     84 }
     85 
     86 bool pca9555_read_pins_all(uint8_t slave_addr, uint16_t* out) {
     87     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
     88 
     89     typedef union {
     90         uint8_t  u8[2];
     91         uint16_t u16;
     92     } data16;
     93 
     94     data16 data = {.u16 = 0};
     95 
     96     i2c_status_t ret = i2c_read_register(addr, CMD_INPUT_0, &data.u8[0], sizeof(data), TIMEOUT);
     97     if (ret != I2C_STATUS_SUCCESS) {
     98         print("pca9555_read_pins_all::FAILED\n");
     99         return false;
    100     }
    101 
    102     *out = data.u16;
    103     return true;
    104 }