From dc570b0b389d23b8ea8b46311294a7040b5e1e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=95=E3=81=8F=E3=82=89=E3=82=93=E3=81=BC?= <47372812+sakurachari@users.noreply.github.com> Date: Fri, 12 Apr 2019 01:07:39 +0900 Subject: Keyboard: Add yosino58 Keyboard (#5465) * Keyboard: Add yosino58 Keyboard * Keyboard: Add yosino58 Keyboard --- keyboards/yosino58/i2c.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 keyboards/yosino58/i2c.c (limited to 'keyboards/yosino58/i2c.c') diff --git a/keyboards/yosino58/i2c.c b/keyboards/yosino58/i2c.c new file mode 100644 index 0000000000..4bee5c6398 --- /dev/null +++ b/keyboards/yosino58/i2c.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include +#include +#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<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< slave ACK +// 1 => slave NACK +uint8_t i2c_master_write(uint8_t data) { + TWDR = data; + TWCR = (1<= 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<