diff options
Diffstat (limited to 'keyboards')
-rw-r--r-- | keyboards/fc660c/actuation_point.c | 87 | ||||
-rw-r--r-- | keyboards/fc660c/ad5258.c | 52 | ||||
-rw-r--r-- | keyboards/fc660c/ad5258.h | 28 | ||||
-rw-r--r-- | keyboards/fc660c/config.h | 2 | ||||
-rw-r--r-- | keyboards/fc660c/fc660c.c | 45 | ||||
-rw-r--r-- | keyboards/fc660c/fc660c.h (renamed from keyboards/fc980c/actuation_point.h) | 8 | ||||
-rw-r--r-- | keyboards/fc660c/i2c.c | 162 | ||||
-rw-r--r-- | keyboards/fc660c/i2c.h | 46 | ||||
-rw-r--r-- | keyboards/fc660c/rules.mk | 6 | ||||
-rw-r--r-- | keyboards/fc980c/actuation_point.c | 87 | ||||
-rw-r--r-- | keyboards/fc980c/ad5258.c | 52 | ||||
-rw-r--r-- | keyboards/fc980c/ad5258.h | 28 | ||||
-rw-r--r-- | keyboards/fc980c/config.h | 2 | ||||
-rw-r--r-- | keyboards/fc980c/fc980c.c | 44 | ||||
-rw-r--r-- | keyboards/fc980c/fc980c.h (renamed from keyboards/fc660c/actuation_point.h) | 8 | ||||
-rw-r--r-- | keyboards/fc980c/i2c.c | 162 | ||||
-rw-r--r-- | keyboards/fc980c/i2c.h | 46 | ||||
-rw-r--r-- | keyboards/fc980c/keymaps/actuation-point-example/config.h | 8 | ||||
-rw-r--r-- | keyboards/fc980c/keymaps/actuation-point-example/keymap.c | 5 | ||||
-rw-r--r-- | keyboards/fc980c/rules.mk | 6 |
20 files changed, 254 insertions, 630 deletions
diff --git a/keyboards/fc660c/actuation_point.c b/keyboards/fc660c/actuation_point.c deleted file mode 100644 index 5f4cb16f40..0000000000 --- a/keyboards/fc660c/actuation_point.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2017 Balz Guenat -based on work by Jun Wako <wakojun@gmail.com> - -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 <http://www.gnu.org/licenses/>. -*/ - -#include "actuation_point.h" -#include "i2c.h" - -/////////////////////////////////////////////////////////////////////////////// -// -// AD5258 I2C digital potentiometer -// http://www.analog.com/media/en/technical-documentation/data-sheets/AD5258.pdf -// -#define AD5258_ADDR 0b0011000 -#define AD5258_INST_RDAC 0x00 -#define AD5258_INST_EEPROM 0x20 - -uint8_t read_rdac(void) { - // read RDAC register - i2c_start_write(AD5258_ADDR); - i2c_master_write(AD5258_INST_RDAC); - i2c_start_read(AD5258_ADDR); - uint8_t ret = i2c_master_read(I2C_NACK); - i2c_master_stop(); - return ret; -}; - -uint8_t read_eeprom(void) { - i2c_start_write(AD5258_ADDR); - i2c_master_write(AD5258_INST_EEPROM); - i2c_start_read(AD5258_ADDR); - uint8_t ret = i2c_master_read(I2C_NACK); - i2c_master_stop(); - return ret; -}; - -void write_rdac(uint8_t rdac) { - // write RDAC register: - i2c_start_write(AD5258_ADDR); - i2c_master_write(AD5258_INST_RDAC); - i2c_master_write(rdac & 0x3F); - i2c_master_stop(); -}; - -void actuation_point_up(void) { - // write RDAC register: lower value makes actuation point shallow - uint8_t rdac = read_rdac(); - if (rdac == 0) - write_rdac(0); - else - write_rdac(rdac-1); -}; - -void actuation_point_down(void) { - // write RDAC register: higher value makes actuation point deep - uint8_t rdac = read_rdac(); - if (rdac == 63) - write_rdac(63); - else - write_rdac(rdac+1); -}; - -void adjust_actuation_point(int offset) { - i2c_master_init(); - uint8_t rdac = read_eeprom() + offset; - if (rdac > 63) { // protects from under and overflows - if (offset > 0) - write_rdac(63); - else - write_rdac(0); - } else { - write_rdac(rdac); - } -} diff --git a/keyboards/fc660c/ad5258.c b/keyboards/fc660c/ad5258.c new file mode 100644 index 0000000000..b1df75789b --- /dev/null +++ b/keyboards/fc660c/ad5258.c @@ -0,0 +1,52 @@ +/* +Copyright 2017 Balz Guenat +based on work by Jun Wako <wakojun@gmail.com> + +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 <http://www.gnu.org/licenses/>. +*/ + +#include "ad5258.h" +#include "i2c_master.h" + +/////////////////////////////////////////////////////////////////////////////// +// +// AD5258 I2C digital potentiometer +// http://www.analog.com/media/en/technical-documentation/data-sheets/AD5258.pdf +// +#define AD5258_I2C_ADDRESS 0x18 +#define AD5258_INST_RDAC 0x00 +#define AD5258_INST_EEPROM 0x20 + +void ad5258_init(void) { + i2c_init(); +} + +uint8_t ad5258_read_rdac(void) { + // read RDAC register + uint8_t ret = 0; + i2c_readReg(AD5258_I2C_ADDRESS, AD5258_INST_RDAC, &ret, 1, 100); + return ret; +} + +uint8_t ad5258_read_eeprom(void) { + uint8_t ret = 0; + i2c_readReg(AD5258_I2C_ADDRESS, AD5258_INST_EEPROM, &ret, 1, 100); + return ret; +} + +void ad5258_write_rdac(uint8_t rdac) { + // write RDAC register: + uint8_t data = rdac & 0x3F; + i2c_writeReg(AD5258_I2C_ADDRESS, AD5258_INST_RDAC, &data, 1, 100); +} diff --git a/keyboards/fc660c/ad5258.h b/keyboards/fc660c/ad5258.h new file mode 100644 index 0000000000..c27f247675 --- /dev/null +++ b/keyboards/fc660c/ad5258.h @@ -0,0 +1,28 @@ +/* +Copyright 2017 Balz Guenat + +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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdint.h> + +void ad5258_init(void); + +uint8_t ad5258_read_rdac(void); + +uint8_t ad5258_read_eeprom(void); + +void ad5258_write_rdac(uint8_t rdac); diff --git a/keyboards/fc660c/config.h b/keyboards/fc660c/config.h index cd23bdb2b8..beff84d9be 100644 --- a/keyboards/fc660c/config.h +++ b/keyboards/fc660c/config.h @@ -27,8 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. * These options are also useful to firmware size reduction. */ -#define USE_I2C - /* disable debug print */ //#define NO_DEBUG diff --git a/keyboards/fc660c/fc660c.c b/keyboards/fc660c/fc660c.c index 2054cd2818..50540cbfb9 100644 --- a/keyboards/fc660c/fc660c.c +++ b/keyboards/fc660c/fc660c.c @@ -14,16 +14,47 @@ 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 <http://www.gnu.org/licenses/>. */ -#include "quantum.h" -#ifdef ACTUATION_DEPTH_ADJUSTMENT -#include "actuation_point.h" -#endif +#include "fc660c.h" -void matrix_init_kb(void) { #ifdef ACTUATION_DEPTH_ADJUSTMENT +void matrix_init_kb(void) { adjust_actuation_point(ACTUATION_DEPTH_ADJUSTMENT); -#endif - matrix_init_user(); + matrix_init_user(); +} + +void actuation_point_up(void) { + // write RDAC register: lower value makes actuation point shallow + uint8_t rdac = ad5258_read_rdac(); + if (rdac == 0) { + ad5258_write_rdac(0); + } else { + ad5258_write_rdac(rdac - 1); + } +} + +void actuation_point_down(void) { + // write RDAC register: higher value makes actuation point deep + uint8_t rdac = ad5258_read_rdac(); + if (rdac == 63) { + ad5258_write_rdac(63); + } else { + ad5258_write_rdac(rdac + 1); + } } + +void adjust_actuation_point(int offset) { + ad5258_init(); + uint8_t rdac = ad5258_read_eeprom() + offset; + if (rdac > 63) { // protects from under and overflows + if (offset > 0) { + ad5258_write_rdac(63); + } else { + ad5258_write_rdac(0); + } + } else { + ad5258_write_rdac(rdac); + } +} +#endif diff --git a/keyboards/fc980c/actuation_point.h b/keyboards/fc660c/fc660c.h index e02832186c..aa98e36be9 100644 --- a/keyboards/fc980c/actuation_point.h +++ b/keyboards/fc660c/fc660c.h @@ -17,13 +17,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #pragma once -#include <stdint.h> +#include "quantum.h" + +#ifdef ACTUATION_DEPTH_ADJUSTMENT +# include "ad5258.h" // see keymaps/actuation-point-example to see how these functions can be used. -uint8_t read_rdac(void); -uint8_t read_eeprom(void); void actuation_point_up(void); void actuation_point_down(void); // be careful with this. void adjust_actuation_point(int offset); +#endif diff --git a/keyboards/fc660c/i2c.c b/keyboards/fc660c/i2c.c deleted file mode 100644 index 084c890c40..0000000000 --- a/keyboards/fc660c/i2c.c +++ /dev/null @@ -1,162 +0,0 @@ -#include <util/twi.h> -#include <avr/io.h> -#include <stdlib.h> -#include <avr/interrupt.h> -#include <util/twi.h> -#include <stdbool.h> -#include "i2c.h" - -#ifdef USE_I2C - -// Limits the amount of we wait for any one i2c transaction. -// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is -// 9 bits, a single transaction will take around 90μs to complete. -// -// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit -// poll loop takes at least 8 clock cycles to execute -#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 - -#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) - -volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; - -static volatile uint8_t slave_buffer_pos; -static volatile bool slave_has_register_set = false; - -// Wait for an i2c operation to finish -inline static -void i2c_delay(void) { - uint16_t lim = 0; - while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT) - lim++; - - // easier way, but will wait slightly longer - // _delay_us(100); -} - -// Setup twi to run at 100kHz -void i2c_master_init(void) { - // no prescaler - TWSR = 0; - // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10. - // Check datasheets for more info. - TWBR = ((F_CPU/SCL_CLOCK)-16)/2; -} - -// Start a transaction with the given i2c slave address. The direction of the -// transfer is set with I2C_READ and I2C_WRITE. -// returns: 0 => success -// 1 => error -uint8_t i2c_master_start(uint8_t address) { - TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); - - i2c_delay(); - - // check that we started successfully - if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) - return 1; - - TWDR = address; - TWCR = (1<<TWINT) | (1<<TWEN); - - i2c_delay(); - - if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) ) - return 1; // slave did not acknowledge - else - return 0; // success -} - - -// Finish the i2c transaction. -void i2c_master_stop(void) { - TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); - - uint16_t lim = 0; - while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT) - lim++; -} - -// Write one byte to the i2c slave. -// returns 0 => slave ACK -// 1 => slave NACK -uint8_t i2c_master_write(uint8_t data) { - TWDR = data; - TWCR = (1<<TWINT) | (1<<TWEN); - - i2c_delay(); - - // check if the slave acknowledged us - return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1; -} - -// Read one byte from the i2c slave. If ack=1 the slave is acknowledged, -// if ack=0 the acknowledge bit is not set. -// returns: byte read from i2c device -uint8_t i2c_master_read(int ack) { - TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); - - i2c_delay(); - return TWDR; -} - -void i2c_reset_state(void) { - TWCR = 0; -} - -void i2c_slave_init(uint8_t address) { - TWAR = address << 0; // slave i2c address - // TWEN - twi enable - // TWEA - enable address acknowledgement - // TWINT - twi interrupt flag - // TWIE - enable the twi interrupt - TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN); -} - -ISR(TWI_vect); - -ISR(TWI_vect) { - uint8_t ack = 1; - switch(TW_STATUS) { - case TW_SR_SLA_ACK: - // this device has been addressed as a slave receiver - slave_has_register_set = false; - break; - - case TW_SR_DATA_ACK: - // this device has received data as a slave receiver - // The first byte that we receive in this transaction sets the location - // of the read/write location of the slaves memory that it exposes over - // i2c. After that, bytes will be written at slave_buffer_pos, incrementing - // slave_buffer_pos after each write. - if(!slave_has_register_set) { - slave_buffer_pos = TWDR; - // don't acknowledge the master if this memory loctaion is out of bounds - if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) { - ack = 0; - slave_buffer_pos = 0; - } - slave_has_register_set = true; - } else { - i2c_slave_buffer[slave_buffer_pos] = TWDR; - BUFFER_POS_INC(); - } - break; - - case TW_ST_SLA_ACK: - case TW_ST_DATA_ACK: - // master has addressed this device as a slave transmitter and is - // requesting data. - TWDR = i2c_slave_buffer[slave_buffer_pos]; - BUFFER_POS_INC(); - break; - - case TW_BUS_ERROR: // something went wrong, reset twi state - TWCR = 0; - default: - break; - } - // Reset everything, so we are ready for the next TWI interrupt - TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); -} -#endif diff --git a/keyboards/fc660c/i2c.h b/keyboards/fc660c/i2c.h deleted file mode 100644 index 8910e70f10..0000000000 --- a/keyboards/fc660c/i2c.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include <stdint.h> - -#ifndef F_CPU -#define F_CPU 16000000UL -#endif - -#define I2C_READ 1 -#define I2C_WRITE 0 - -#define I2C_ACK 1 -#define I2C_NACK 0 - -#define SLAVE_BUFFER_SIZE 0x10 - -// i2c SCL clock frequency -#define SCL_CLOCK 400000L - -extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; - -void i2c_master_init(void); -uint8_t i2c_master_start(uint8_t address); -void i2c_master_stop(void); -uint8_t i2c_master_write(uint8_t data); -uint8_t i2c_master_read(int); -void i2c_reset_state(void); -void i2c_slave_init(uint8_t address); - - -static inline unsigned char i2c_start_read(unsigned char addr) { - return i2c_master_start((addr << 1) | I2C_READ); -} - -static inline unsigned char i2c_start_write(unsigned char addr) { - return i2c_master_start((addr << 1) | I2C_WRITE); -} - -// from SSD1306 scrips -extern unsigned char i2c_rep_start(unsigned char addr); -extern void i2c_start_wait(unsigned char addr); -extern unsigned char i2c_readAck(void); -extern unsigned char i2c_readNak(void); -extern unsigned char i2c_read(unsigned char ack); - -#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); diff --git a/keyboards/fc660c/rules.mk b/keyboards/fc660c/rules.mk index ed4a7ca66d..52f4ce803d 100644 --- a/keyboards/fc660c/rules.mk +++ b/keyboards/fc660c/rules.mk @@ -11,7 +11,7 @@ NKRO_ENABLE = yes # Enable N-Key Rollover # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax +QUANTUM_LIB_SRC += i2c_master.c + CUSTOM_MATRIX = yes -SRC += matrix.c \ - actuation_point.c \ - i2c.c +SRC += matrix.c ad5258.c diff --git a/keyboards/fc980c/actuation_point.c b/keyboards/fc980c/actuation_point.c deleted file mode 100644 index 5f4cb16f40..0000000000 --- a/keyboards/fc980c/actuation_point.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2017 Balz Guenat -based on work by Jun Wako <wakojun@gmail.com> - -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 <http://www.gnu.org/licenses/>. -*/ - -#include "actuation_point.h" -#include "i2c.h" - -/////////////////////////////////////////////////////////////////////////////// -// -// AD5258 I2C digital potentiometer -// http://www.analog.com/media/en/technical-documentation/data-sheets/AD5258.pdf -// -#define AD5258_ADDR 0b0011000 -#define AD5258_INST_RDAC 0x00 -#define AD5258_INST_EEPROM 0x20 - -uint8_t read_rdac(void) { - // read RDAC register - i2c_start_write(AD5258_ADDR); - i2c_master_write(AD5258_INST_RDAC); - i2c_start_read(AD5258_ADDR); - uint8_t ret = i2c_master_read(I2C_NACK); - i2c_master_stop(); - return ret; -}; - -uint8_t read_eeprom(void) { - i2c_start_write(AD5258_ADDR); - i2c_master_write(AD5258_INST_EEPROM); - i2c_start_read(AD5258_ADDR); - uint8_t ret = i2c_master_read(I2C_NACK); - i2c_master_stop(); - return ret; -}; - -void write_rdac(uint8_t rdac) { - // write RDAC register: - i2c_start_write(AD5258_ADDR); - i2c_master_write(AD5258_INST_RDAC); - i2c_master_write(rdac & 0x3F); - i2c_master_stop(); -}; - -void actuation_point_up(void) { - // write RDAC register: lower value makes actuation point shallow - uint8_t rdac = read_rdac(); - if (rdac == 0) - write_rdac(0); - else - write_rdac(rdac-1); -}; - -void actuation_point_down(void) { - // write RDAC register: higher value makes actuation point deep - uint8_t rdac = read_rdac(); - if (rdac == 63) - write_rdac(63); - else - write_rdac(rdac+1); -}; - -void adjust_actuation_point(int offset) { - i2c_master_init(); - uint8_t rdac = read_eeprom() + offset; - if (rdac > 63) { // protects from under and overflows - if (offset > 0) - write_rdac(63); - else - write_rdac(0); - } else { - write_rdac(rdac); - } -} diff --git a/keyboards/fc980c/ad5258.c b/keyboards/fc980c/ad5258.c new file mode 100644 index 0000000000..b1df75789b --- /dev/null +++ b/keyboards/fc980c/ad5258.c @@ -0,0 +1,52 @@ +/* +Copyright 2017 Balz Guenat +based on work by Jun Wako <wakojun@gmail.com> + +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 <http://www.gnu.org/licenses/>. +*/ + +#include "ad5258.h" +#include "i2c_master.h" + +/////////////////////////////////////////////////////////////////////////////// +// +// AD5258 I2C digital potentiometer +// http://www.analog.com/media/en/technical-documentation/data-sheets/AD5258.pdf +// +#define AD5258_I2C_ADDRESS 0x18 +#define AD5258_INST_RDAC 0x00 +#define AD5258_INST_EEPROM 0x20 + +void ad5258_init(void) { + i2c_init(); +} + +uint8_t ad5258_read_rdac(void) { + // read RDAC register + uint8_t ret = 0; + i2c_readReg(AD5258_I2C_ADDRESS, AD5258_INST_RDAC, &ret, 1, 100); + return ret; +} + +uint8_t ad5258_read_eeprom(void) { + uint8_t ret = 0; + i2c_readReg(AD5258_I2C_ADDRESS, AD5258_INST_EEPROM, &ret, 1, 100); + return ret; +} + +void ad5258_write_rdac(uint8_t rdac) { + // write RDAC register: + uint8_t data = rdac & 0x3F; + i2c_writeReg(AD5258_I2C_ADDRESS, AD5258_INST_RDAC, &data, 1, 100); +} diff --git a/keyboards/fc980c/ad5258.h b/keyboards/fc980c/ad5258.h new file mode 100644 index 0000000000..c27f247675 --- /dev/null +++ b/keyboards/fc980c/ad5258.h @@ -0,0 +1,28 @@ +/* +Copyright 2017 Balz Guenat + +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 <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdint.h> + +void ad5258_init(void); + +uint8_t ad5258_read_rdac(void); + +uint8_t ad5258_read_eeprom(void); + +void ad5258_write_rdac(uint8_t rdac); diff --git a/keyboards/fc980c/config.h b/keyboards/fc980c/config.h index 7c0c3b31a6..776b8ef35f 100644 --- a/keyboards/fc980c/config.h +++ b/keyboards/fc980c/config.h @@ -30,8 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. * These options are also useful to firmware size reduction. */ -#define USE_I2C - /* disable debug print */ //#define NO_DEBUG diff --git a/keyboards/fc980c/fc980c.c b/keyboards/fc980c/fc980c.c index fc3696f244..c1c62da9ac 100644 --- a/keyboards/fc980c/fc980c.c +++ b/keyboards/fc980c/fc980c.c @@ -15,16 +15,46 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "quantum.h" +#include "fc980c.h" #ifdef ACTUATION_DEPTH_ADJUSTMENT -#include "actuation_point.h" -#endif - void matrix_init_kb(void) { -#ifdef ACTUATION_DEPTH_ADJUSTMENT adjust_actuation_point(ACTUATION_DEPTH_ADJUSTMENT); -#endif - matrix_init_user(); + matrix_init_user(); +} + +void actuation_point_up(void) { + // write RDAC register: lower value makes actuation point shallow + uint8_t rdac = ad5258_read_rdac(); + if (rdac == 0) { + ad5258_write_rdac(0); + } else { + ad5258_write_rdac(rdac - 1); + } } + +void actuation_point_down(void) { + // write RDAC register: higher value makes actuation point deep + uint8_t rdac = ad5258_read_rdac(); + if (rdac == 63) { + ad5258_write_rdac(63); + } else { + ad5258_write_rdac(rdac + 1); + } +} + +void adjust_actuation_point(int offset) { + ad5258_init(); + uint8_t rdac = ad5258_read_eeprom() + offset; + if (rdac > 63) { // protects from under and overflows + if (offset > 0) { + ad5258_write_rdac(63); + } else { + ad5258_write_rdac(0); + } + } else { + ad5258_write_rdac(rdac); + } +} +#endif diff --git a/keyboards/fc660c/actuation_point.h b/keyboards/fc980c/fc980c.h index e02832186c..aa98e36be9 100644 --- a/keyboards/fc660c/actuation_point.h +++ b/keyboards/fc980c/fc980c.h @@ -17,13 +17,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #pragma once -#include <stdint.h> +#include "quantum.h" + +#ifdef ACTUATION_DEPTH_ADJUSTMENT +# include "ad5258.h" // see keymaps/actuation-point-example to see how these functions can be used. -uint8_t read_rdac(void); -uint8_t read_eeprom(void); void actuation_point_up(void); void actuation_point_down(void); // be careful with this. void adjust_actuation_point(int offset); +#endif diff --git a/keyboards/fc980c/i2c.c b/keyboards/fc980c/i2c.c deleted file mode 100644 index 084c890c40..0000000000 --- a/keyboards/fc980c/i2c.c +++ /dev/null @@ -1,162 +0,0 @@ -#include <util/twi.h> -#include <avr/io.h> -#include <stdlib.h> -#include <avr/interrupt.h> -#include <util/twi.h> -#include <stdbool.h> -#include "i2c.h" - -#ifdef USE_I2C - -// Limits the amount of we wait for any one i2c transaction. -// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is -// 9 bits, a single transaction will take around 90μs to complete. -// -// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit -// poll loop takes at least 8 clock cycles to execute -#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8 - -#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE) - -volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; - -static volatile uint8_t slave_buffer_pos; -static volatile bool slave_has_register_set = false; - -// Wait for an i2c operation to finish -inline static -void i2c_delay(void) { - uint16_t lim = 0; - while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT) - lim++; - - // easier way, but will wait slightly longer - // _delay_us(100); -} - -// Setup twi to run at 100kHz -void i2c_master_init(void) { - // no prescaler - TWSR = 0; - // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10. - // Check datasheets for more info. - TWBR = ((F_CPU/SCL_CLOCK)-16)/2; -} - -// Start a transaction with the given i2c slave address. The direction of the -// transfer is set with I2C_READ and I2C_WRITE. -// returns: 0 => success -// 1 => error -uint8_t i2c_master_start(uint8_t address) { - TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA); - - i2c_delay(); - - // check that we started successfully - if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START)) - return 1; - - TWDR = address; - TWCR = (1<<TWINT) | (1<<TWEN); - - i2c_delay(); - - if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) ) - return 1; // slave did not acknowledge - else - return 0; // success -} - - -// Finish the i2c transaction. -void i2c_master_stop(void) { - TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); - - uint16_t lim = 0; - while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT) - lim++; -} - -// Write one byte to the i2c slave. -// returns 0 => slave ACK -// 1 => slave NACK -uint8_t i2c_master_write(uint8_t data) { - TWDR = data; - TWCR = (1<<TWINT) | (1<<TWEN); - - i2c_delay(); - - // check if the slave acknowledged us - return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1; -} - -// Read one byte from the i2c slave. If ack=1 the slave is acknowledged, -// if ack=0 the acknowledge bit is not set. -// returns: byte read from i2c device -uint8_t i2c_master_read(int ack) { - TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA); - - i2c_delay(); - return TWDR; -} - -void i2c_reset_state(void) { - TWCR = 0; -} - -void i2c_slave_init(uint8_t address) { - TWAR = address << 0; // slave i2c address - // TWEN - twi enable - // TWEA - enable address acknowledgement - // TWINT - twi interrupt flag - // TWIE - enable the twi interrupt - TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN); -} - -ISR(TWI_vect); - -ISR(TWI_vect) { - uint8_t ack = 1; - switch(TW_STATUS) { - case TW_SR_SLA_ACK: - // this device has been addressed as a slave receiver - slave_has_register_set = false; - break; - - case TW_SR_DATA_ACK: - // this device has received data as a slave receiver - // The first byte that we receive in this transaction sets the location - // of the read/write location of the slaves memory that it exposes over - // i2c. After that, bytes will be written at slave_buffer_pos, incrementing - // slave_buffer_pos after each write. - if(!slave_has_register_set) { - slave_buffer_pos = TWDR; - // don't acknowledge the master if this memory loctaion is out of bounds - if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) { - ack = 0; - slave_buffer_pos = 0; - } - slave_has_register_set = true; - } else { - i2c_slave_buffer[slave_buffer_pos] = TWDR; - BUFFER_POS_INC(); - } - break; - - case TW_ST_SLA_ACK: - case TW_ST_DATA_ACK: - // master has addressed this device as a slave transmitter and is - // requesting data. - TWDR = i2c_slave_buffer[slave_buffer_pos]; - BUFFER_POS_INC(); - break; - - case TW_BUS_ERROR: // something went wrong, reset twi state - TWCR = 0; - default: - break; - } - // Reset everything, so we are ready for the next TWI interrupt - TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN); -} -#endif diff --git a/keyboards/fc980c/i2c.h b/keyboards/fc980c/i2c.h deleted file mode 100644 index 8910e70f10..0000000000 --- a/keyboards/fc980c/i2c.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include <stdint.h> - -#ifndef F_CPU -#define F_CPU 16000000UL -#endif - -#define I2C_READ 1 -#define I2C_WRITE 0 - -#define I2C_ACK 1 -#define I2C_NACK 0 - -#define SLAVE_BUFFER_SIZE 0x10 - -// i2c SCL clock frequency -#define SCL_CLOCK 400000L - -extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE]; - -void i2c_master_init(void); -uint8_t i2c_master_start(uint8_t address); -void i2c_master_stop(void); -uint8_t i2c_master_write(uint8_t data); -uint8_t i2c_master_read(int); -void i2c_reset_state(void); -void i2c_slave_init(uint8_t address); - - -static inline unsigned char i2c_start_read(unsigned char addr) { - return i2c_master_start((addr << 1) | I2C_READ); -} - -static inline unsigned char i2c_start_write(unsigned char addr) { - return i2c_master_start((addr << 1) | I2C_WRITE); -} - -// from SSD1306 scrips -extern unsigned char i2c_rep_start(unsigned char addr); -extern void i2c_start_wait(unsigned char addr); -extern unsigned char i2c_readAck(void); -extern unsigned char i2c_readNak(void); -extern unsigned char i2c_read(unsigned char ack); - -#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); diff --git a/keyboards/fc980c/keymaps/actuation-point-example/config.h b/keyboards/fc980c/keymaps/actuation-point-example/config.h index c2a538b6ae..a4ecab70fd 100644 --- a/keyboards/fc980c/keymaps/actuation-point-example/config.h +++ b/keyboards/fc980c/keymaps/actuation-point-example/config.h @@ -14,11 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef CONFIG_USER_H -#define CONFIG_USER_H - - -// place overrides here +#pragma once // higher value means deeper actuation point, less sensitive // be careful and only make small adjustments (steps of 1 or 2). @@ -27,5 +23,3 @@ // this should probably stay in the range +/-5. #undef ACTUATION_DEPTH_ADJUSTMENT #define ACTUATION_DEPTH_ADJUSTMENT +1 - -#endif diff --git a/keyboards/fc980c/keymaps/actuation-point-example/keymap.c b/keyboards/fc980c/keymaps/actuation-point-example/keymap.c index 85e782d625..50b6a9ff40 100644 --- a/keyboards/fc980c/keymaps/actuation-point-example/keymap.c +++ b/keyboards/fc980c/keymaps/actuation-point-example/keymap.c @@ -15,7 +15,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include QMK_KEYBOARD_H -#include "actuation_point.h" enum custom_keycodes { @@ -62,12 +61,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) } case AP_READ_RDAC: { - xprintf("RDAC: %d", read_rdac()); + xprintf("RDAC: %d", ad5258_read_rdac()); return false; } case AP_READ_EEPROM: { - xprintf("EEPROM: %d", read_eeprom()); + xprintf("EEPROM: %d", ad5258_read_eeprom()); return false; } diff --git a/keyboards/fc980c/rules.mk b/keyboards/fc980c/rules.mk index ed4a7ca66d..52f4ce803d 100644 --- a/keyboards/fc980c/rules.mk +++ b/keyboards/fc980c/rules.mk @@ -11,7 +11,7 @@ NKRO_ENABLE = yes # Enable N-Key Rollover # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax +QUANTUM_LIB_SRC += i2c_master.c + CUSTOM_MATRIX = yes -SRC += matrix.c \ - actuation_point.c \ - i2c.c +SRC += matrix.c ad5258.c |