qmk_firmware

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

pca9505.c (3699B)


      1 // Copyright 2022 nirim000
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #include "i2c_master.h"
      5 #include "pca9505.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_INPUT_2,
     16     CMD_INPUT_3,
     17     CMD_INPUT_4,
     18     CMD_OUTPUT_0 = 8,
     19     CMD_OUTPUT_1,
     20     CMD_OUTPUT_2,
     21     CMD_OUTPUT_3,
     22     CMD_OUTPUT_4,
     23     CMD_INVERSION_0 = 16,
     24     CMD_INVERSION_1,
     25     CMD_INVERSION_2,
     26     CMD_INVERSION_3,
     27     CMD_INVERSION_4,
     28     CMD_CONFIG_0 = 24,
     29     CMD_CONFIG_1,
     30     CMD_CONFIG_2,
     31     CMD_CONFIG_3,
     32     CMD_CONFIG_4,
     33 };
     34 
     35 void pca9505_init(uint8_t slave_addr) {
     36     static uint8_t s_init = 0;
     37     if (!s_init) {
     38         i2c_init();
     39 
     40         s_init = 1;
     41     }
     42 
     43     // TODO: could check device connected
     44 }
     45 
     46 bool pca9505_set_config(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
     47     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
     48     uint8_t cmd  = 0;
     49     switch (port) {
     50         case 0:
     51             cmd = CMD_CONFIG_0;
     52             break;
     53         case 1:
     54             cmd = CMD_CONFIG_1;
     55             break;
     56         case 2:
     57             cmd = CMD_CONFIG_2;
     58             break;
     59         case 3:
     60             cmd = CMD_CONFIG_3;
     61             break;
     62         case 4:
     63             cmd = CMD_CONFIG_4;
     64             break;
     65     }
     66 
     67     i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
     68     if (ret != I2C_STATUS_SUCCESS) {
     69         print("pca9505_set_config::FAILED\n");
     70         return false;
     71     }
     72 
     73     return true;
     74 }
     75 
     76 bool pca9505_set_polarity(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
     77     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
     78     uint8_t cmd  = 0;
     79     switch (port) {
     80         case 0:
     81             cmd = CMD_INVERSION_0;
     82             break;
     83         case 1:
     84             cmd = CMD_INVERSION_1;
     85             break;
     86         case 2:
     87             cmd = CMD_INVERSION_2;
     88             break;
     89         case 3:
     90             cmd = CMD_INVERSION_3;
     91             break;
     92         case 4:
     93             cmd = CMD_INVERSION_4;
     94             break;
     95     }
     96 
     97     i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
     98     if (ret != I2C_STATUS_SUCCESS) {
     99         print("pca9505_set_polarity::FAILED\n");
    100         return false;
    101     }
    102 
    103     return true;
    104 }
    105 
    106 bool pca9505_set_output(uint8_t slave_addr, pca9505_port_t port, uint8_t conf) {
    107     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
    108     uint8_t cmd  = 0;
    109     switch (port) {
    110         case 0:
    111             cmd = CMD_OUTPUT_0;
    112             break;
    113         case 1:
    114             cmd = CMD_OUTPUT_1;
    115             break;
    116         case 2:
    117             cmd = CMD_OUTPUT_2;
    118             break;
    119         case 3:
    120             cmd = CMD_OUTPUT_3;
    121             break;
    122         case 4:
    123             cmd = CMD_OUTPUT_4;
    124             break;
    125     }
    126 
    127     i2c_status_t ret = i2c_write_register(addr, cmd, &conf, sizeof(conf), TIMEOUT);
    128     if (ret != I2C_STATUS_SUCCESS) {
    129         print("pca9505_set_output::FAILED\n");
    130         return false;
    131     }
    132 
    133     return true;
    134 }
    135 
    136 bool pca9505_read_pins(uint8_t slave_addr, pca9505_port_t port, uint8_t* out) {
    137     uint8_t addr = SLAVE_TO_ADDR(slave_addr);
    138     uint8_t cmd  = 0;
    139     switch (port) {
    140         case 0:
    141             cmd = CMD_INPUT_0;
    142             break;
    143         case 1:
    144             cmd = CMD_INPUT_1;
    145             break;
    146         case 2:
    147             cmd = CMD_INPUT_2;
    148             break;
    149         case 3:
    150             cmd = CMD_INPUT_3;
    151             break;
    152         case 4:
    153             cmd = CMD_INPUT_4;
    154             break;
    155     }
    156 
    157     i2c_status_t ret = i2c_read_register(addr, cmd, out, sizeof(uint8_t), TIMEOUT);
    158     if (ret != I2C_STATUS_SUCCESS) {
    159         print("pca9505_read_pins::FAILED\n");
    160         return false;
    161     }
    162 
    163     return true;
    164 }