Skip to content

Commit

Permalink
Keyboard: Add yosino58 Keyboard (qmk#5465)
Browse files Browse the repository at this point in the history
* Keyboard: Add yosino58 Keyboard

* Keyboard: Add yosino58 Keyboard
  • Loading branch information
sakurachari authored and Timbus committed Jun 23, 2019
1 parent 0489a3b commit dcf1902
Show file tree
Hide file tree
Showing 38 changed files with 4,019 additions and 0 deletions.
34 changes: 34 additions & 0 deletions keyboards/yosino58/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright 2012 Jun Wako <[email protected]>
Copyright 2015 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "config_common.h"
#include <serial_config.h>

#define USE_I2C
#define USE_SERIAL

#ifdef USE_Link_Time_Optimization
// LTO has issues with macros (action_get_macro) and "functions" (fn_actions),
// so just disable them
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION

#define DISABLE_LEADER
#endif // USE_Link_Time_Optimization
162 changes: 162 additions & 0 deletions keyboards/yosino58/i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#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 or 400kHz (see ./i2c.h SCL_CLOCK)
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
46 changes: 46 additions & 0 deletions keyboards/yosino58/i2c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#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 400kHz
#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();
20 changes: 20 additions & 0 deletions keyboards/yosino58/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"keyboard_name": "yosino58 rev. 1",
"url": "https://github.com/sakurachari/yosino58",
"maintainer": "sakuranbo0046",
"width": 16.75,
"height": 6.25,
"layouts": {
"LAYOUT": {
"key_count": 58,
"layout": [
{"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":0.25}, {"x":3, "y":0}, {"x":4, "y":0.25}, {"x":5, "y":0.5}, {"x":10.75, "y":0.5}, {"x":11.75, "y":0.25}, {"x":12.75, "y":0}, {"x":13.75, "y":0.25}, {"x":14.75, "y":1}, {"x":15.75, "y":1},
{"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":1.25}, {"x":3, "y":1}, {"x":4, "y":1.25}, {"x":5, "y":1.5}, {"x":10.75, "y":1.5}, {"x":11.75, "y":1.25}, {"x":12.75, "y":1}, {"x":13.75, "y":1.25}, {"x":14.75, "y":2}, {"x":15.75, "y":2},
{"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":2.25}, {"x":3, "y":2}, {"x":4, "y":2.25}, {"x":5, "y":2.5}, {"x":10.75, "y":2.5}, {"x":11.75, "y":2.25}, {"x":12.75, "y":2}, {"x":13.75, "y":2.25}, {"x":14.75, "y":3}, {"x":15.75, "y":3},
{"x":0, "y":4}, {"x":1, "y":4}, {"x":2, "y":3.25}, {"x":3, "y":3}, {"x":4, "y":3.25}, {"x":5, "y":3.5}, {"x":6.5, "y":4.25}, {"x":7.5, "y":4.25, "h":2}, {"x":8.5, "y":4.25, "h":2}, {"x":9.5, "y":4.25}, {"x":10.75, "y":3.5}, {"x":11.75, "y":3.25}, {"x":12.75, "y":3}, {"x":13.75, "y":3.25}, {"x":14.75, "y":4}, {"x":15.75, "y":4},
{"x":3.75, "y":4.25}, {"x":4.75, "y":4.5}, {"x":6.5, "y":5.25}, {"x":9.5, "y":5.25}, {"x":11, "y":4.5}, {"x":12, "y":4.25}
]
}
}
}

43 changes: 43 additions & 0 deletions keyboards/yosino58/keymaps/default/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
This is the c configuration file for the keymap
Copyright 2012 Jun Wako <[email protected]>
Copyright 2015 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

//#define USE_MATRIX_I2C

/* Select hand configuration */

#define MASTER_LEFT
// #define MASTER_RIGHT
// #define EE_HANDS

#define SSD1306OLED
// #define SSD1306_128X64

#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100

#undef RGBLED_NUM
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12
#define RGBLIGHT_LIMIT_VAL 120
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
Loading

0 comments on commit dcf1902

Please sign in to comment.