diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index 2a7badd351..f53cb394a7 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c @@ -43,7 +43,12 @@ static const I2CConfig i2cconfig = { void i2c_init(void) { - palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); // Try releasing special pins for a short time + //palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); + + // Try releasing special pins for a short time + palSetPadMode(GPIOB, 6, PAL_MODE_INPUT); + palSetPadMode(GPIOB, 7, PAL_MODE_INPUT); + chThdSleepMilliseconds(10); palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); @@ -74,6 +79,10 @@ uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t ti return i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout)); } +uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length) { + return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, tx_body, tx_length, rx_body, rx_length, MS2ST(100)); +} + uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { i2c_address = devaddr; diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h index 591fa7f77d..392760328f 100644 --- a/drivers/arm/i2c_master.h +++ b/drivers/arm/i2c_master.h @@ -34,6 +34,7 @@ void i2c_init(void); uint8_t i2c_start(uint8_t address); uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); +uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_stop(uint16_t timeout); diff --git a/drivers/qwiic/joystiic.c b/drivers/qwiic/joystiic.c new file mode 100644 index 0000000000..ac97a22cd7 --- /dev/null +++ b/drivers/qwiic/joystiic.c @@ -0,0 +1,184 @@ +/* Copyright 2018 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "joystiic.h" +#include "print.h" +#include "action.h" + +#define JOYSTIIC_DEFAULT_ADDR 0x20 +#define JOYSTIIC_COMMAND_HORIZONTAL 0x00 +#define JOYSTIIC_COMMAND_VERTICAL 0x02 +#define JOYSTIIC_COMMAND_BUTTON 0x04 + +#define JOYSTIIC_CENTER 512 +#define JOYSTIIC_DEADZONE 200 + +uint16_t joystiic_horizontal; +uint16_t joystiic_vertical; +bool joystiic_button; + +uint8_t joystiic_tx[1]; +uint8_t joystiic_rx_horizontal[2]; +uint8_t joystiic_rx_vertical[2]; +uint8_t joystiic_rx_button[1]; + +enum { + JOYSTIIC_LEFT, + JOYSTIIC_RIGHT, + JOYSTIIC_UP, + JOYSTIIC_DOWN, + JOYSTIIC_PRESS +}; + +bool joystiic_triggered[5] = {0}; + +void joystiic_init(void) { + i2c_init(); + i2c_start(JOYSTIIC_DEFAULT_ADDR); +} + +void joystiic_update(uint16_t horizontal, uint16_t vertical, bool button) { + joystiic_update_kb(horizontal, vertical, button); + joystiic_update_user(horizontal, vertical, button); +} + +void joystiic_update_kb(uint16_t horizontal, uint16_t vertical, bool button) { + +} + +void joystiic_update_user(uint16_t horizontal, uint16_t vertical, bool button) { + +} + +void joystiic_trigger(uint8_t trigger, bool active) { + joystiic_trigger_kb(trigger, active); + joystiic_trigger_user(trigger, active); +} + +void joystiic_trigger_kb(uint8_t trigger, bool active) { + switch (trigger) { + case JOYSTIIC_LEFT: active ? register_code(KC_L) : unregister_code(KC_L); break; + } +} + +void joystiic_trigger_user(uint8_t trigger, bool active) { + +} + +void joystiic_task(void) { + // get horizontal axis + joystiic_tx[0] = JOYSTIIC_COMMAND_HORIZONTAL; + + if (MSG_OK != i2c_transmit_receive(JOYSTIIC_DEFAULT_ADDR << 1, + joystiic_tx, 1, + joystiic_rx_horizontal, 2 + )) { + printf("error hori\n"); + } + + joystiic_horizontal = ((uint16_t)joystiic_rx_horizontal[0] << 8) | joystiic_rx_horizontal[1]; + + if (joystiic_horizontal > (JOYSTIIC_CENTER + JOYSTIIC_DEADZONE)) { + if (!joystiic_triggered[JOYSTIIC_LEFT]) { + joystiic_triggered[JOYSTIIC_LEFT] = true; + joystiic_trigger(JOYSTIIC_LEFT, true); + } + } else { + if (joystiic_triggered[JOYSTIIC_LEFT]) { + joystiic_triggered[JOYSTIIC_LEFT] = false; + joystiic_trigger(JOYSTIIC_LEFT, false); + } + } + + if (joystiic_horizontal < (JOYSTIIC_CENTER - JOYSTIIC_DEADZONE)) { + if (!joystiic_triggered[JOYSTIIC_RIGHT]) { + joystiic_triggered[JOYSTIIC_RIGHT] = true; + joystiic_trigger(JOYSTIIC_RIGHT, true); + } + } else { + if (joystiic_triggered[JOYSTIIC_RIGHT]) { + joystiic_triggered[JOYSTIIC_RIGHT] = false; + joystiic_trigger(JOYSTIIC_RIGHT, false); + } + } + + // get vertical axis + joystiic_tx[0] = JOYSTIIC_COMMAND_VERTICAL; + if (MSG_OK != i2c_transmit_receive(JOYSTIIC_DEFAULT_ADDR << 1, + joystiic_tx, 1, + joystiic_rx_vertical, 2 + )) { + printf("error vert\n"); + } + + joystiic_vertical = ((uint16_t)joystiic_rx_vertical[0] << 8) | joystiic_rx_vertical[1]; + + if (joystiic_vertical > (JOYSTIIC_CENTER + JOYSTIIC_DEADZONE)) { + if (!joystiic_triggered[JOYSTIIC_UP]) { + joystiic_triggered[JOYSTIIC_UP] = true; + joystiic_trigger(JOYSTIIC_UP, true); + } + } else { + if (joystiic_triggered[JOYSTIIC_UP]) { + joystiic_triggered[JOYSTIIC_UP] = false; + joystiic_trigger(JOYSTIIC_UP, false); + } + } + + if (joystiic_vertical < (JOYSTIIC_CENTER - JOYSTIIC_DEADZONE)) { + if (!joystiic_triggered[JOYSTIIC_DOWN]) { + joystiic_triggered[JOYSTIIC_DOWN] = true; + joystiic_trigger(JOYSTIIC_DOWN, true); + } + } else { + if (joystiic_triggered[JOYSTIIC_DOWN]) { + joystiic_triggered[JOYSTIIC_DOWN] = false; + joystiic_trigger(JOYSTIIC_DOWN, false); + } + } + + // get button press + joystiic_tx[0] = JOYSTIIC_COMMAND_BUTTON; + if (MSG_OK != i2c_transmit_receive(JOYSTIIC_DEFAULT_ADDR << 1, + joystiic_tx, 1, + joystiic_rx_button, 1 + )) { + printf("error vert\n"); + } + + joystiic_button = joystiic_rx_button[0]; + + if (joystiic_button) { + if (!joystiic_triggered[JOYSTIIC_PRESS]) { + joystiic_triggered[JOYSTIIC_PRESS] = true; + joystiic_trigger(JOYSTIIC_PRESS, true); + } + } else { + if (joystiic_triggered[JOYSTIIC_PRESS]) { + joystiic_triggered[JOYSTIIC_PRESS] = false; + joystiic_trigger(JOYSTIIC_PRESS, false); + } + } + + joystiic_update(joystiic_horizontal, joystiic_vertical, joystiic_button); + + //printf("%d\n", joystiic[0]); + + // SEND_STRING("H: "); + // send_word(joystiic_rx_horizontal[0]); + // tap_code(KC_SPACE); + // send_word(joystiic_rx_horizontal[1]); + // tap_code(KC_SPACE); +} diff --git a/drivers/qwiic/joystiic.h b/drivers/qwiic/joystiic.h new file mode 100644 index 0000000000..808f1a626e --- /dev/null +++ b/drivers/qwiic/joystiic.h @@ -0,0 +1,26 @@ +/* Copyright 2018 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include "i2c_master.h" + +void joystiic_update_kb(uint16_t horizontal, uint16_t vertical, bool button); +void joystiic_update_user(uint16_t horizontal, uint16_t vertical, bool button); +void joystiic_trigger_kb(uint8_t trigger, bool active); +void joystiic_trigger_user(uint8_t trigger, bool active); + +void joystiic_init(void); +void joystiic_task(void); diff --git a/keyboards/planck/rev6/halconf.h b/keyboards/planck/rev6/halconf.h index 8fe8e0c6f5..c3e0cbb728 100644 --- a/keyboards/planck/rev6/halconf.h +++ b/keyboards/planck/rev6/halconf.h @@ -76,7 +76,7 @@ * @brief Enables the I2C subsystem. */ #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) -#define HAL_USE_I2C FALSE +#define HAL_USE_I2C TRUE #endif /** diff --git a/keyboards/planck/rev6/mcuconf.h b/keyboards/planck/rev6/mcuconf.h index 7c3c6e570c..36f8ca2252 100644 --- a/keyboards/planck/rev6/mcuconf.h +++ b/keyboards/planck/rev6/mcuconf.h @@ -154,7 +154,7 @@ /* * I2C driver system settings. */ -#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C1 TRUE #define STM32_I2C_USE_I2C2 FALSE #define STM32_I2C_BUSY_TIMEOUT 50 #define STM32_I2C_I2C1_IRQ_PRIORITY 10 diff --git a/keyboards/planck/rev6/rev6.c b/keyboards/planck/rev6/rev6.c index 650e1a194d..e4b5365f99 100644 --- a/keyboards/planck/rev6/rev6.c +++ b/keyboards/planck/rev6/rev6.c @@ -14,11 +14,14 @@ * along with this program. If not, see . */ #include "rev6.h" +#include "qwiic/joystiic.h" void matrix_init_kb(void) { matrix_init_user(); + joystiic_init(); } void matrix_scan_kb(void) { matrix_scan_user(); + joystiic_task(); } diff --git a/keyboards/planck/rev6/rules.mk b/keyboards/planck/rev6/rules.mk index 3603e287b3..c3e9f23afb 100644 --- a/keyboards/planck/rev6/rules.mk +++ b/keyboards/planck/rev6/rules.mk @@ -1,5 +1,5 @@ # project specific files -SRC = matrix.c +SRC = matrix.c qwiic/joystiic.c i2c_master.c LAYOUTS += ortho_4x12 ## chip/board settings