summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerryMathews <terry@terrymathews.net>2020-03-18 21:13:12 -0400
committerGitHub <noreply@github.com>2020-03-19 01:13:12 +0000
commit19d7cbc8584ed5c0ec1f768a27767496eeae66f8 (patch)
tree3a699d143690057c510e8f20d99adb6d26631ef1
parent73f903906ee86e70c301da2f1d70a22f58cdbdf1 (diff)
M0lly: refactor OLED support and qmk-dfu bootloader (#8475)
-rw-r--r--keyboards/m0lly/config.h5
-rw-r--r--keyboards/m0lly/i2c.c166
-rw-r--r--keyboards/m0lly/i2c.h49
-rw-r--r--keyboards/m0lly/keymaps/default/config.h24
-rw-r--r--keyboards/m0lly/keymaps/default/keymap.c101
-rw-r--r--keyboards/m0lly/rules.mk8
6 files changed, 31 insertions, 322 deletions
diff --git a/keyboards/m0lly/config.h b/keyboards/m0lly/config.h
index 010833ac80..327b0f08c1 100644
--- a/keyboards/m0lly/config.h
+++ b/keyboards/m0lly/config.h
@@ -67,6 +67,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
+#define QMK_ESC_OUTPUT A0 // usually COL
+#define QMK_ESC_INPUT F4 // usually ROW
+#define QMK_LED D2 // NumLock on M0lly
+//#define QMK_SPEAKER C6
+
/*
* Force NKRO
*
diff --git a/keyboards/m0lly/i2c.c b/keyboards/m0lly/i2c.c
deleted file mode 100644
index cd2b835d50..0000000000
--- a/keyboards/m0lly/i2c.c
+++ /dev/null
@@ -1,166 +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<<TWSTA) | (1<<TWEN);
-
- i2c_delay();
-
- // check that we started successfully
- if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
- return 1;
-
- // send device address
- 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/m0lly/i2c.h b/keyboards/m0lly/i2c.h
deleted file mode 100644
index 2bd7f40968..0000000000
--- a/keyboards/m0lly/i2c.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef I2C_H
-#define I2C_H
-
-#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 800000L
-
-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();
-
-#endif
diff --git a/keyboards/m0lly/keymaps/default/config.h b/keyboards/m0lly/keymaps/default/config.h
deleted file mode 100644
index ee142927f3..0000000000
--- a/keyboards/m0lly/keymaps/default/config.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright 2017 Mathias Andersson <wraul@dbox.se>
- *
- * 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_I2C
-#define SSD1306OLED
-//#define OLED_ROTATE180
-#define SSD1306_ADDRESS 0x3C
-
-// place overrides here
diff --git a/keyboards/m0lly/keymaps/default/keymap.c b/keyboards/m0lly/keymaps/default/keymap.c
index 784deb04a7..5f6211f0f5 100644
--- a/keyboards/m0lly/keymaps/default/keymap.c
+++ b/keyboards/m0lly/keymaps/default/keymap.c
@@ -13,11 +13,8 @@
* 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 "LUFA/Drivers/Peripheral/TWI.h"
-#include "i2c.h"
-#include "ssd1306.h"
-
//Layers
@@ -26,13 +23,6 @@ enum {
FUNCTION,
};
-bool screenWorks = 0;
-
-//13 characters max without re-writing the "Layer: " format in iota_gfx_task_user()
-static char layer_lookup[][14] = {"Base","Function"};
-
-
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap BASE: (Base Layer) Default Layer
*
@@ -78,72 +68,27 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
),
};
-bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- return true;
-}
-
-void led_set_user(uint8_t usb_led) {
-
-}
-
-void matrix_init_user(void) {
- #ifdef USE_I2C
- i2c_master_init();
- #ifdef SSD1306OLED
- // calls code for the SSD1306 OLED
- _delay_ms(400);
- TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
- if ( iota_gfx_init() ) { // turns on the display
- screenWorks = 1;
- }
- #endif
- #endif
- #ifdef AUDIO_ENABLE
- startup_user();
- #endif
-}
-
-void matrix_scan_user(void) {
- #ifdef SSD1306OLED
- if ( screenWorks ) {
- iota_gfx_task(); // this is what updates the display continuously
- };
- #endif
-}
-
-void matrix_update(struct CharacterMatrix *dest,
- const struct CharacterMatrix *source) {
- if (memcmp(dest->display, source->display, sizeof(dest->display))) {
- memcpy(dest->display, source->display, sizeof(dest->display));
- dest->dirty = true;
- }
-}
-
-void iota_gfx_task_user(void) {
- #if DEBUG_TO_SCREEN
- if (debug_enable) {
- return;
+#ifdef OLED_DRIVER_ENABLE
+void oled_task_user(void) {
+ oled_write_P(PSTR("TKC1800\n"),false);
+ // Host Keyboard Layer Status
+ oled_write_P(PSTR("Layer: "), false);
+
+ switch (get_highest_layer(layer_state)) {
+ case BASE:
+ oled_write_P(PSTR("Base\n"), false);
+ break;
+ case FUNCTION:
+ oled_write_P(PSTR("Function\n"), false);
+ break;
+ default:
+ // Or use the write_ln shortcut over adding '\n' to the end of your string
+ oled_write_ln_P(PSTR("Undefined"), false);
}
- #endif
-
- struct CharacterMatrix matrix;
-
- matrix_clear(&matrix);
- matrix_write_P(&matrix, PSTR("TKC M0LLY"));
-
- uint8_t layer = biton32(layer_state);
-
- char buf[40];
- snprintf(buf,sizeof(buf), "Undef-%d", layer);
- matrix_write_P(&matrix, PSTR("\nLayer: "));
- matrix_write(&matrix, layer_lookup[layer]);
-
- // Host Keyboard LED Status
- char led[40];
- snprintf(led, sizeof(led), "\n\n%s %s %s",
- (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
- (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
- (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
- matrix_write(&matrix, led);
- matrix_update(&display, &matrix);
+ // Host Keyboard LED Status
+ led_t led_state = host_keyboard_led_state();
+ oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
+ oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
+ oled_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false);
}
+#endif \ No newline at end of file
diff --git a/keyboards/m0lly/rules.mk b/keyboards/m0lly/rules.mk
index 60140160c2..05e6290759 100644
--- a/keyboards/m0lly/rules.mk
+++ b/keyboards/m0lly/rules.mk
@@ -9,12 +9,12 @@ MCU = at90usb1286
# QMK DFU qmk-dfu
# ATmega32A bootloadHID
# ATmega328P USBasp
-BOOTLOADER = atmel-dfu
+BOOTLOADER = qmk-dfu
# Build Options
# change yes to no to disable
#
-BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = yes # Console for debug
@@ -29,6 +29,4 @@ MIDI_ENABLE = no # MIDI controls
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no # Audio output on port C6
-
-SRC = i2c.c \
- ssd1306.c
+OLED_DRIVER_ENABLE = yes \ No newline at end of file