diff --git a/keyboard/kimera/Makefile b/keyboard/kimera/Makefile index 96f7dd28..cccec58c 100644 --- a/keyboard/kimera/Makefile +++ b/keyboard/kimera/Makefile @@ -52,6 +52,7 @@ SRC = keymap_common.c \ matrix.c \ led.c \ backlight.c \ + twimaster.c \ kimera.c ifdef KEYMAP @@ -117,7 +118,7 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096 ifdef VER OPT_DEFS += -DKIMERA_$(REV) else - OPT_DEFS += -DKIMERA_V2 + OPT_DEFS += -DKIMERA_V5 endif # Additional definitions from command line diff --git a/keyboard/kimera/Makefile.pjrc b/keyboard/kimera/Makefile.pjrc index afbb0a03..140e64c4 100644 --- a/keyboard/kimera/Makefile.pjrc +++ b/keyboard/kimera/Makefile.pjrc @@ -52,12 +52,13 @@ SRC = keymap_common.c \ matrix.c \ led.c \ backlight.c \ + twimaster.c \ kimera.c ifdef KEYMAP SRC := keymap_$(KEYMAP).c $(SRC) else - SRC := keymap_poker.c $(SRC) + SRC := keymap_default.c $(SRC) endif CONFIG_H = config.h diff --git a/keyboard/kimera/Makefile_3300 b/keyboard/kimera/Makefile_8M similarity index 99% rename from keyboard/kimera/Makefile_3300 rename to keyboard/kimera/Makefile_8M index 8b465f74..bced6dee 100644 --- a/keyboard/kimera/Makefile_3300 +++ b/keyboard/kimera/Makefile_8M @@ -39,7 +39,7 @@ #---------------------------------------------------------------------------- # Target file name (without extension). -TARGET = kimera_lufa_3300 +TARGET = kimera_8m_lufa # Directory common source filess exist TOP_DIR = ../.. @@ -52,6 +52,7 @@ SRC = keymap_common.c \ matrix.c \ led.c \ backlight.c \ + twimaster.c \ kimera.c ifdef KEYMAP diff --git a/keyboard/kimera/backlight.c b/keyboard/kimera/backlight.c index 10564411..a0a6f473 100644 --- a/keyboard/kimera/backlight.c +++ b/keyboard/kimera/backlight.c @@ -33,14 +33,14 @@ static const uint8_t backlight_table[] PROGMEM = { }; /* Backlight pin configuration - * BL: PB5 (D9) + * LED4: PB6 (D10) OC1B */ void backlight_enable(void) { // Turn on PWM - BL_DDR |= (1<. /* USB Device descriptor parameter */ #define VENDOR_ID 0x16c0 #define PRODUCT_ID 0x27db -#define DEVICE_VER 0x0001 +#define DEVICE_VER 0x0005 #define MANUFACTURER kai1103@gmail.com #define PRODUCT Kimera #define DESCRIPTION t.m.k. keyboard firmware for Kimera diff --git a/keyboard/kimera/i2cmaster.h b/keyboard/kimera/i2cmaster.h new file mode 100644 index 00000000..70f51fd3 --- /dev/null +++ b/keyboard/kimera/i2cmaster.h @@ -0,0 +1,178 @@ +#ifndef _I2CMASTER_H +#define _I2CMASTER_H 1 +/************************************************************************* +* Title: C include file for the I2C master interface +* (i2cmaster.S or twimaster.c) +* Author: Peter Fleury http://jump.to/fleury +* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $ +* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3 +* Target: any AVR device +* Usage: see Doxygen manual +**************************************************************************/ + +#ifdef DOXYGEN +/** + @defgroup pfleury_ic2master I2C Master library + @code #include @endcode + + @brief I2C (TWI) Master Software Library + + Basic routines for communicating with I2C slave devices. This single master + implementation is limited to one bus master on the I2C bus. + + This I2c library is implemented as a compact assembler software implementation of the I2C protocol + which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c). + Since the API for these two implementations is exactly the same, an application can be linked either against the + software I2C implementation or the hardware I2C implementation. + + Use 4.7k pull-up resistor on the SDA and SCL pin. + + Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module + i2cmaster.S to your target when using the software I2C implementation ! + + Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion. + + @note + The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted + to GNU assembler and AVR-GCC C call interface. + Replaced the incorrect quarter period delays found in AVR300 with + half period delays. + + @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury + + @par API Usage Example + The following code shows typical usage of this library, see example test_i2cmaster.c + + @code + + #include + + + #define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet + + int main(void) + { + unsigned char ret; + + i2c_init(); // initialize I2C library + + // write 0x75 to EEPROM address 5 (Byte Write) + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + i2c_write(0x05); // write address = 5 + i2c_write(0x75); // write value 0x75 to EEPROM + i2c_stop(); // set stop conditon = release bus + + + // read previously written value back from EEPROM address 5 + i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode + + i2c_write(0x05); // write address = 5 + i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode + + ret = i2c_readNak(); // read one byte from EEPROM + i2c_stop(); + + for(;;); + } + @endcode + +*/ +#endif /* DOXYGEN */ + +/**@{*/ + +#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 +#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" +#endif + +#include + +/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */ +#define I2C_READ 1 + +/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */ +#define I2C_WRITE 0 + + +/** + @brief initialize the I2C master interace. Need to be called only once + @param void + @return none + */ +extern void i2c_init(void); + + +/** + @brief Terminates the data transfer and releases the I2C bus + @param void + @return none + */ +extern void i2c_stop(void); + + +/** + @brief Issues a start condition and sends address and transfer direction + + @param addr address and transfer direction of I2C device + @retval 0 device accessible + @retval 1 failed to access device + */ +extern unsigned char i2c_start(unsigned char addr); + + +/** + @brief Issues a repeated start condition and sends address and transfer direction + + @param addr address and transfer direction of I2C device + @retval 0 device accessible + @retval 1 failed to access device + */ +extern unsigned char i2c_rep_start(unsigned char addr); + + +/** + @brief Issues a start condition and sends address and transfer direction + + If device is busy, use ack polling to wait until device ready + @param addr address and transfer direction of I2C device + @return none + */ +extern void i2c_start_wait(unsigned char addr); + + +/** + @brief Send one byte to I2C device + @param data byte to be transfered + @retval 0 write successful + @retval 1 write failed + */ +extern unsigned char i2c_write(unsigned char data); + + +/** + @brief read one byte from the I2C device, request more data from device + @return byte read from I2C device + */ +extern unsigned char i2c_readAck(void); + +/** + @brief read one byte from the I2C device, read is followed by a stop condition + @return byte read from I2C device + */ +extern unsigned char i2c_readNak(void); + +/** + @brief read one byte from the I2C device + + Implemented as a macro, which calls either i2c_readAck or i2c_readNak + + @param ack 1 send ack, request more data from device
+ 0 send nak, read is followed by a stop condition + @return byte read from I2C device + */ +extern unsigned char i2c_read(unsigned char ack); +#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak(); + + +/**@}*/ +#endif diff --git a/keyboard/kimera/kimera.c b/keyboard/kimera/kimera.c index 7c0f4aca..d79c13ca 100644 --- a/keyboard/kimera/kimera.c +++ b/keyboard/kimera/kimera.c @@ -20,88 +20,73 @@ along with this program. If not, see . #include #include #include +#include "i2cmaster.h" #include "kimera.h" #include "debug.h" -uint8_t mux_mapping[MUX_COUNT] = { - MUX_FOR_ROW, MUX_FOR_COL, MUX_FOR_COL, MUX_FOR_COL -}; -uint8_t row_mapping[MATRIX_ROWS] = { +uint8_t row_mapping[PX_COUNT] = { 0, 1, 2, 3, 4, 5, 6, 7, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, + UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED }; -uint8_t col_mapping[MATRIX_COLS] = { +uint8_t col_mapping[PX_COUNT] = { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31 + 24, 25, 26, 27, 28, 29, 30, 31, + UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED, UNCONFIGURED }; -uint8_t row_max_count = MUX_PORTS * 1; -uint8_t col_max_count = MUX_PORTS * (MUX_COUNT - 1); -uint16_t shift_out_cache = 0; +uint8_t row_count = 8; +uint8_t col_count = 24; +uint8_t data[EXP_COUNT][EXP_PORT_COUNT]; void kimera_init(void) { - // read config - write_matrix_mapping(); + /* read config */ + write_matrix_mapping(); /* debug */ if (read_matrix_mapping()) { write_matrix_mapping(); } - // init shift out pins - MOSI_DDR |= (1< PX_COUNT) error++; - for (uint8_t mux = 0; mux < MUX_COUNT; mux++) { - mux_mapping[mux] = mux_config & (1 << mux); - if (mux_mapping[mux] == MUX_FOR_COL) { - col_max_count += MUX_PORTS; + /* read row mapping */ + uint8_t *mapping = EECONFIG_ROW_COL_MAPPING; + for (uint8_t i = 0; i < PX_COUNT; i++) { + if (i < row_count) { + row_mapping[i] = eeprom_read_byte(mapping++); + if (row_mapping[i] >= PX_COUNT) error++; } else { - row_max_count += MUX_PORTS; + row_mapping[i] = UNCONFIGURED; } } - if ((col_max_count == 0) || (row_max_count == 0)) { - error++; - } - - uint8_t *mapping = EECONFIG_ROW_COL_MAPPING; - for (uint8_t row = 0; row < row_max_count; row++) { - row_mapping[row] = eeprom_read_byte(mapping++); - if (row_mapping[row] != UNCONFIGURED) { - if (mux_mapping[PX_TO_MUX(row_mapping[row])] != MUX_FOR_ROW) { - row_mapping[row] = UNCONFIGURED; - error++; - } + /* read col mapping*/ + for (uint8_t i = 0; i < PX_COUNT; i++) { + if (i < col_count) { + col_mapping[i] = eeprom_read_byte(mapping++); + if (col_mapping[i] >= PX_COUNT) error++; } - } - for (uint8_t col = 0; col < col_max_count; col++) { - col_mapping[col] = eeprom_read_byte(mapping++); - if (col_mapping[col] != UNCONFIGURED) { - if (mux_mapping[PX_TO_MUX(col_mapping[col])] != MUX_FOR_COL) { - col_mapping[col] = UNCONFIGURED; - error++; - } + else { + col_mapping[i] = UNCONFIGURED; } } @@ -110,66 +95,36 @@ uint8_t read_matrix_mapping(void) void write_matrix_mapping(void) { - uint8_t mux_config = 0; - row_max_count = 0; - col_max_count = 0; - - for (uint8_t mux = 0; mux < MUX_COUNT; mux++) { - mux_config |= (mux_mapping[mux] << mux); - if (mux_mapping[mux] == MUX_FOR_COL) { - col_max_count += MUX_PORTS; - } - else { - row_max_count += MUX_PORTS; - } - } - eeprom_write_byte(EECONFIG_MUX_MAPPING, mux_config); + /* write number of rows and cols */ + eeprom_write_byte(EECONFIG_ROW_COUNT, row_count); + eeprom_write_byte(EECONFIG_COL_COUNT, col_count); + /* write row mapping */ uint8_t *mapping = EECONFIG_ROW_COL_MAPPING; - for (uint8_t row = 0; row < row_max_count; row++) { + for (uint8_t row = 0; row < row_count; row++) { eeprom_write_byte(mapping++, row_mapping[row]); } - for (uint8_t col = 0; col < col_max_count; col++) { + /* write col mapping */ + for (uint8_t col = 0; col < col_count; col++) { eeprom_write_byte(mapping++, col_mapping[col]); } } -void shift_out_word(uint16_t data) -{ - SPDR = ((data>>8) & 0xFF); - while (!(SPSR & (1<. #include "matrix.h" /* - Pro Micro + U1 (Pro Micro) ,----------------. TX --| TX0(PD3) RAW |-- RX --| RX1(PD2) GND |-- --| GND RESET |-- RST --| GND VCC |-- - SDA --| 2(PD1) (PF4)A3 |-- (Z4) - SCL --| 3(PD0) (PF5)A2 |-- (Z1) - (RCK) --| 4(PD4) (PF6)A1 |-- (Z2) - LED1 --| 5(PC6) (PF7)A0 |-- (Z3) - LED2 --| 6(PD7) (PB1)15 |-- SCK - (SJ1) --| 7(PE6) (PB3)14 |-- MISO - (SJ2) --| 8(PB4) (PB2)16 |-- MOSI - BL --| 9(PB5) (PB6)10 |-- LED3 + SDA --| 2(PD1) (PF4)A3 |-- + SCL --| 3(PD0) (PF5)A2 |-- + (INT) --| 4(PD4) (PF6)A1 |-- + --| 5(PC6) (PF7)A0 |-- + --| 6(PD7) (PB1)15 |-- SCK + LED2 --| 7(PE6) (PB3)14 |-- MISO + LED1 --| 8(PB4) (PB2)16 |-- MOSI + LED3 --| 9(PB5) (PB6)10 |-- LED4 `----------------' */ -#define LED1_PORT PORTC -#define LED1_PIN PINC -#define LED1_DDR DDRC -#define LED1_BIT PC6 +#define LED1_PORT PORTB +#define LED1_PIN PINB +#define LED1_DDR DDRB +#define LED1_BIT PB4 -#define LED2_PORT PORTD -#define LED2_PIN PIND -#define LED2_DDR DDRD -#define LED2_BIT PD7 +#define LED2_PORT PORTE +#define LED2_PIN PINE +#define LED2_DDR DDRE +#define LED2_BIT PE6 #define LED3_PORT PORTB #define LED3_PIN PINB #define LED3_DDR DDRB -#define LED3_BIT PB6 +#define LED3_BIT PB5 -#define BL_PORT PORTB -#define BL_PIN PINB -#define BL_DDR DDRB -#define BL_BIT PB5 -#define BL_OCR OCR1A - -#define RCK_PORT PORTD -#define RCK_PIN PIND -#define RCK_DDR DDRD -#define RCK_BIT PD4 - -#define SCK_PORT PORTB -#define SCK_PIN PINB -#define SCK_DDR DDRB -#define SCK_BIT PB1 - -#define MOSI_PORT PORTB -#define MOSI_PIN PINB -#define MOSI_DDR DDRB -#define MOSI_BIT PB2 - -#define MISO_PORT PORTB -#define MISO_PIN PINB -#define MISO_DDR DDRB -#define MISO_BIT PB3 - -#define ZX_PORT PORTF -#define ZX_PIN PINF -#define ZX_DDR DDRF -#ifdef KIMERA_C -const uint8_t PROGMEM zx_bit[] = { - PF5, PF6, PF7, PF4 -}; -#endif -#define MUX_TO_ZX_BIT(x) (pgm_read_byte(zx_bit + (x))) +#define LED4_PORT PORTB +#define LED4_PIN PINB +#define LED4_DDR DDRB +#define LED4_BIT PB6 +#define LED4_OCR OCR1B /* - - Shift Register Multiplexer - ,----------. ,------------. - MOSI --| SER 0 |----| INH X0~X7 |===============. - SCK --|>SCK 1 |----| C | | - RCK --|>RCK 2 |----| B | ,-------------+-------------. - | 3 |----| A | | | | | | | | | - | | `------------' P26 P27 P28 P25 P29 P32 P30 P31 - | | ,------------. - | 4 |----| C X0~X7 |===============. - | 5 |----| B | | - | 6 |----| A | ,-------------+-------------. - | 7 |----| INH | | | | | | | | | - | | `------------' P2 P3 P4 P1 P5 P8 P6 P7 - | | ,------------. - | 8 |----| INH X0~X7 |===============. - | 9 |----| C | | - | 10 |----| B | ,-------------+-------------. - | 11 |----| A | | | | | | | | | - | | `------------' P10 P11 P12 P9 P13 P16 P14 P15 - | | ,------------. - | 12 |----| C X0~X7 |===============. - | 13 |----| B | | - | 14 |----| A | ,-------------+-------------. - | 15 |----| INH | | | | | | | | | - `----------' `------------' P18 P19 P20 P17 P21 P24 P22 P23 + IC1 (PCA9555) IC2 (PCA9555) + ,----------. ,----------. + SDA --| SDA P00 |-- P1 SDA --| SDA P00 |-- P9 + SCL --| SCL P01 |-- P2 SCL --| SCL P01 |-- P10 + INT --| INT P02 |-- P3 INT --| INT P02 |-- P11 + | P03 |-- P4 | P03 |-- P12 + GND --| A0 P04 |-- P5 VCC --| A0 P04 |-- P13 + SJ1 --| A1 P05 |-- P6 SJ1 --| A1 P05 |-- P14 + SJ2 --| A2 P06 |-- P7 SJ2 --| A2 P06 |-- P15 + | P07 |-- P8 | P07 |-- P16 + | | | | + | P10 |-- P25 | P10 |-- P17 + | P11 |-- P26 | P11 |-- P18 + | P12 |-- P27 | P12 |-- P19 + | P13 |-- P28 | P13 |-- P20 + | P14 |-- P29 | P14 |-- P21 + | P15 |-- P30 | P15 |-- P22 + | P16 |-- P31 | P16 |-- P23 + | P17 |-- P32 | P17 |-- P24 + `----------' `----------' */ -#define MUX_COUNT 4 -#define MUX_PORTS 8 -#define PX_TO_MUX(x) (x>>3) // (x / MUX_PORTS) - -#if defined(KIMERA_V1) +#define EXP_COUNT 2 +#define EXP_ADDR(n) ((0x20+(n))<<1) +#define EXP_OUTPUT 0 +#define EXP_INPUT 1 +#define EXP_PORT_COUNT 2 +#define EXP_PIN_PER_PORT 8 enum { - MUX4_INH = 0, - MUX4_A, - MUX4_B, - MUX4_C, - MUX1_A, - MUX1_B, - MUX1_C, - MUX1_INH, - MUX2_INH, - MUX2_A, - MUX2_B, - MUX2_C, - MUX3_A, - MUX3_B, - MUX3_C, - MUX3_INH + EXP_COMM_INPUT_0 = 0, + EXP_COMM_INPUT_1, + EXP_COMM_OUTPUT_0, + EXP_COMM_OUTPUT_1, + EXP_COMM_INVERSION_0, + EXP_COMM_INVERSION_1, + EXP_COMM_CONFIG_0, + EXP_COMM_CONFIG_1 }; -#elif defined(KIMERA_V2) -enum { - MUX4_INH = 0, - MUX4_C, - MUX4_B, - MUX4_A, - MUX1_C, - MUX1_B, - MUX1_A, - MUX1_INH, - MUX2_INH, - MUX2_C, - MUX2_B, - MUX2_A, - MUX3_C, - MUX3_B, - MUX3_A, - MUX3_INH -}; -#endif +#define PX_TO_EXP(x) (((x)>>5<<1)+((((x)>>3)&1)^(((x)>>4)&1))) +#define PX_TO_PORT(x) (((x)>>4)&1) +#define PX_TO_PIN(x) ((x)&7) +#define PX_COUNT (EXP_PIN_PER_PORT * EXP_PORT_COUNT * EXP_COUNT) #ifdef KIMERA_C -#if defined(KIMERA_V1) -const uint16_t PROGMEM px_to_shift_out[] = { - 3< 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 + +#include +#include "debug.h" + + +/* define CPU frequency in Mhz here if not defined in Makefile */ +#ifndef F_CPU +#define F_CPU 4000000UL +#endif + +/* I2C clock in Hz */ +#define SCL_CLOCK 400000L + + +/************************************************************************* + 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 */ + +}/* 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<