From 93b017b095f882dab3f7e568b86bcab5ea49e369 Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Fri, 31 Oct 2014 15:30:32 +0900 Subject: [PATCH] kimera: Implement i2c auto-scan and timeout --- keyboard/kimera/Makefile | 2 +- keyboard/kimera/kimera.c | 83 ++++++++++++-- keyboard/kimera/kimera.h | 5 +- keyboard/kimera/matrix.c | 4 + keyboard/kimera/twimaster.c | 220 ++++++++++++++++++------------------ 5 files changed, 194 insertions(+), 120 deletions(-) diff --git a/keyboard/kimera/Makefile b/keyboard/kimera/Makefile index cccec58c..e6ecf532 100644 --- a/keyboard/kimera/Makefile +++ b/keyboard/kimera/Makefile @@ -140,7 +140,7 @@ NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA #PS2_USE_BUSYWAIT = yes BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality KEYMAP_IN_EEPROM_ENABLE = yes # External keymap in eeprom -KEYMAP_SECTION_ENABLE = yes # Fixed address keymap for keymap editor +#KEYMAP_SECTION_ENABLE = yes # Fixed address keymap for keymap editor BREATHING_LED_ENABLE = yes # Enable breathing backlight # Optimize size but this may cause error "relocation truncated to fit" diff --git a/keyboard/kimera/kimera.c b/keyboard/kimera/kimera.c index d79c13ca..5f02a87c 100644 --- a/keyboard/kimera/kimera.c +++ b/keyboard/kimera/kimera.c @@ -19,11 +19,18 @@ along with this program. If not, see . #include #include +#include +#include #include +#include "action.h" +#include "suspend.h" #include "i2cmaster.h" #include "kimera.h" #include "debug.h" +#define SCL_CLOCK 400000L +extern uint8_t i2c_force_stop; + uint8_t row_mapping[PX_COUNT] = { 0, 1, 2, 3, 4, 5, 6, 7, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, @@ -39,6 +46,7 @@ uint8_t col_mapping[PX_COUNT] = { uint8_t row_count = 8; uint8_t col_count = 24; uint8_t data[EXP_COUNT][EXP_PORT_COUNT]; +uint8_t exp_status = 0; void kimera_init(void) { @@ -51,8 +59,19 @@ void kimera_init(void) /* init i2c */ i2c_init(); - /* init i/o expander */ - expander_init(); + /* init i/o expanders */ + kimera_scan(); + + /* init watch dog */ + wdt_init(); +} + +void wdt_init(void) +{ + cli(); + wdt_reset(); + wdt_intr_enable(WDTO_1S); + sei(); } uint8_t read_matrix_mapping(void) @@ -110,9 +129,34 @@ void write_matrix_mapping(void) } } +void kimera_scan(void) +{ + wdt_reset(); + uint8_t ret; + for (uint8_t exp = 0; exp < EXP_COUNT; exp++) { + ret = i2c_start(EXP_ADDR(exp) | I2C_READ); + if (exp_status & (1< http://jump.to/fleury -* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $ -* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 -* Target: any AVR device with hardware TWI -* Usage: API compatible with I2C Software Library i2cmaster.h -**************************************************************************/ + * Title: I2C master library using hardware TWI interface + * Author: Peter Fleury http://jump.to/fleury + * File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $ + * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 + * Target: any AVR device with hardware TWI + * Usage: API compatible with I2C Software Library i2cmaster.h + **************************************************************************/ #include #include @@ -21,60 +21,62 @@ /* I2C clock in Hz */ #define SCL_CLOCK 400000L +volatile uint8_t i2c_force_stop = 0; +#define CHECK_FORCE_STOP() if(i2c_force_stop){i2c_force_stop=0;break;} /************************************************************************* - Initialization of the I2C bus interface. Need to be called only once -*************************************************************************/ + Initialization of the I2C bus interface. Need to be called only once + *************************************************************************/ void i2c_init(void) { - /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ - - TWSR = 0; /* no prescaler */ - TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ + /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */ + + TWSR = 0; /* no prescaler */ + TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */ }/* i2c_init */ -/************************************************************************* +/************************************************************************* Issues a start condition and sends address and transfer direction. return 0 = device accessible, 1= failed to access device -*************************************************************************/ + *************************************************************************/ unsigned char i2c_start(unsigned char address) { uint8_t twst; - // send START condition - TWCR = (1<