From f70f45ee677a2a39a759052a356e0c5d82e25424 Mon Sep 17 00:00:00 2001 From: James Laird-Wah Date: Fri, 28 Sep 2018 00:40:18 +1000 Subject: RGB Matrix refactoring to open up for new drivers (#3913) * rgb_matrix: use a driver ops struct This is intended to avoid #ifdef proliferation on adding more drivers, eg. model01, which use different architectures. * rgb_matrix: document driver struct members * rgb_matrix: remove unused LED testing code * rgb_matrix: don't build into IS31x drivers unless being used * rgb_matrix: refactor make config options This ensures that the necessary files are included for any custom RGB_MATRIX_ENABLE value, without having to add entries here for specific boards. This particularly affects model01 because its controller is integrated and won't be used anywhere else, so it's preferable not to put it in common_features.mk. This now validates the value of RGB_MATRIX_ENABLE. It was necessary to fix an error in ergodox_ez rules.mk using the wrong comment separator, yielding an invalid value. * IS31x drivers: don't write the control registers all the time This is only needed when they are changed. This is done in init() and board- or keymap-specific code is free to make further changes. * rgb_matrix: move structs from chip drivers to rgb_matrix_drivers.c This approach is specific to the rgb_matrix functionality, so keep it neatly separated from the raw chip drivers. --- drivers/issi/is31fl3731.c | 1 - drivers/issi/is31fl3733.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/issi/is31fl3731.c b/drivers/issi/is31fl3731.c index 4d0d6b8a5..c9155f5a3 100644 --- a/drivers/issi/is31fl3731.c +++ b/drivers/issi/is31fl3731.c @@ -268,4 +268,3 @@ void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) } } } - diff --git a/drivers/issi/is31fl3733.c b/drivers/issi/is31fl3733.c index 4098b5468..c198ec517 100644 --- a/drivers/issi/is31fl3733.c +++ b/drivers/issi/is31fl3733.c @@ -24,10 +24,10 @@ #include "wait.h" #endif -#include "is31fl3733.h" #include #include "i2c_master.h" #include "progmem.h" +#include "rgb_matrix.h" // This is a 7-bit address, that gets left-shifted and bit 0 // set to 0 for write, 1 for read (as per I2C protocol) @@ -250,4 +250,3 @@ void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) } } } - -- cgit v1.2.3 From 13e166d9c42845e2622605e94d4a0c38fa5443a0 Mon Sep 17 00:00:00 2001 From: Wilba6582 Date: Fri, 28 Sep 2018 00:40:44 +1000 Subject: RAMA U80-A, wilba.tech WT60-A, WT65-A, WT80-A, IS31FL3736 driver (#3925) * Initial commit of RAMA U80-A * Initial commit of RAMA U80-A * Moved IS31FL3736 driver, minor cleanups * Superficial stuff * Review changes * Refactored to use common code. --- drivers/issi/is31fl3736.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/issi/is31fl3736.h | 172 ++++++++++++++++++++++++++ 2 files changed, 478 insertions(+) create mode 100644 drivers/issi/is31fl3736.c create mode 100644 drivers/issi/is31fl3736.h (limited to 'drivers') diff --git a/drivers/issi/is31fl3736.c b/drivers/issi/is31fl3736.c new file mode 100644 index 000000000..c5d431097 --- /dev/null +++ b/drivers/issi/is31fl3736.c @@ -0,0 +1,306 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * 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 . + */ + + +#ifdef __AVR__ +#include +#include +#include +#else +#include "wait.h" +#endif + +#include "is31fl3736.h" +#include +#include "i2c_master.h" +#include "progmem.h" + + + +// This is a 7-bit address, that gets left-shifted and bit 0 +// set to 0 for write, 1 for read (as per I2C protocol) +// The address will vary depending on your wiring: +// 00 <-> GND +// 01 <-> SCL +// 10 <-> SDA +// 11 <-> VCC +// ADDR1 represents A1:A0 of the 7-bit address. +// ADDR2 represents A3:A2 of the 7-bit address. +// The result is: 0b101(ADDR2)(ADDR1) +#define ISSI_ADDR_DEFAULT 0x50 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE +#define ISSI_INTERRUPTMASKREGISTER 0xF0 +#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 + +#define ISSI_PAGE_LEDCONTROL 0x00 //PG0 +#define ISSI_PAGE_PWM 0x01 //PG1 +#define ISSI_PAGE_AUTOBREATH 0x02 //PG2 +#define ISSI_PAGE_FUNCTION 0x03 //PG3 + +#define ISSI_REG_CONFIGURATION 0x00 //PG3 +#define ISSI_REG_GLOBALCURRENT 0x01 //PG3 +#define ISSI_REG_RESET 0x11// PG3 +#define ISSI_REG_SWPULLUP 0x0F //PG3 +#define ISSI_REG_CSPULLUP 0x10 //PG3 + +#ifndef ISSI_TIMEOUT + #define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE + #define ISSI_PERSISTENCE 0 +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the IS31FL3736 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3736_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[DRIVER_COUNT][192]; +bool g_pwm_buffer_update_required = false; + +uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } }; +bool g_led_control_registers_update_required = false; + +void IS31FL3736_write_register( uint8_t addr, uint8_t reg, uint8_t data ) +{ + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + + #if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) + break; + } + #else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); + #endif +} + +void IS31FL3736_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) +{ + // assumes PG1 is already selected + + // transmit PWM registers in 12 transfers of 16 bytes + // g_twi_transfer_buffer[] is 20 bytes + + // iterate over the pwm_buffer contents at 16 byte intervals + for ( int i = 0; i < 192; i += 16 ) { + g_twi_transfer_buffer[0] = i; + // copy the data from i to i+15 + // device will auto-increment register for data after the first byte + // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer + for ( int j = 0; j < 16; j++ ) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + + #if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) + break; + } + #else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); + #endif + } +} + +void IS31FL3736_init( uint8_t addr ) +{ + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, shutdown is enabled last. + // Set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + + // Unlock the command register. + IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + + // Select PG0 + IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); + // Turn off all LEDs. + for ( int i = 0x00; i <= 0x17; i++ ) + { + IS31FL3736_write_register( addr, i, 0x00 ); + } + + // Unlock the command register. + IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + + // Select PG1 + IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); + // Set PWM on all LEDs to 0 + // No need to setup Breath registers to PWM as that is the default. + for ( int i = 0x00; i <= 0xBF; i++ ) + { + IS31FL3736_write_register( addr, i, 0x00 ); + } + + // Unlock the command register. + IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + + // Select PG3 + IS31FL3736_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION ); + // Set global current to maximum. + IS31FL3736_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF ); + // Disable software shutdown. + IS31FL3736_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 ); + + // Wait 10ms to ensure the device has woken up. + #ifdef __AVR__ + _delay_ms( 10 ); + #else + wait_ms(10); + #endif +} + +void IS31FL3736_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) +{ + if ( index >= 0 && index < DRIVER_LED_TOTAL ) { + is31_led led = g_is31_leds[index]; + + g_pwm_buffer[led.driver][led.r] = red; + g_pwm_buffer[led.driver][led.g] = green; + g_pwm_buffer[led.driver][led.b] = blue; + g_pwm_buffer_update_required = true; + } +} + +void IS31FL3736_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) +{ + for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) + { + IS31FL3736_set_color( i, red, green, blue ); + } +} + +void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, bool blue ) +{ + is31_led led = g_is31_leds[index]; + + // IS31FL3733 + // The PWM register for a matrix position (0x00 to 0xBF) can be + // divided by 8 to get the LED control register (0x00 to 0x17), + // then mod 8 to get the bit position within that register. + + // IS31FL3736 + // The PWM register for a matrix position (0x00 to 0xBF) is interleaved, so: + // A1=0x00 A2=0x02 A3=0x04 A4=0x06 A5=0x08 A6=0x0A A7=0x0C A8=0x0E + // B1=0x10 B2=0x12 B3=0x14 + // But also, the LED control registers (0x00 to 0x17) are also interleaved, so: + // A1-A4=0x00 A5-A8=0x01 + // So, the same math applies. + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if ( red ) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if ( green ) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if ( blue ) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required = true; + +} + +void IS31FL3736_mono_set_brightness( int index, uint8_t value ) +{ + if ( index >= 0 && index < 96 ) { + // Index in range 0..95 -> A1..A8, B1..B8, etc. + // Map index 0..95 to registers 0x00..0xBE (interleaved) + uint8_t pwm_register = index * 2; + g_pwm_buffer[0][pwm_register] = value; + g_pwm_buffer_update_required = true; + } +} + +void IS31FL3736_mono_set_brightness_all( uint8_t value ) +{ + for ( int i = 0; i < 96; i++ ) + { + IS31FL3736_mono_set_brightness( i, value ); + } +} + +void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled ) +{ + // Index in range 0..95 -> A1..A8, B1..B8, etc. + + // Map index 0..95 to registers 0x00..0xBE (interleaved) + uint8_t pwm_register = index * 2; + // Map register 0x00..0xBE (interleaved) into control register and bit + uint8_t control_register = pwm_register / 8; + uint8_t bit = pwm_register % 8; + + if ( enabled ) { + g_led_control_registers[0][control_register] |= (1 << bit); + } else { + g_led_control_registers[0][control_register] &= ~(1 << bit); + } + + g_led_control_registers_update_required = true; +} + +void IS31FL3736_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ) +{ + if ( g_pwm_buffer_update_required ) + { + // Firstly we need to unlock the command register and select PG1 + IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM ); + + IS31FL3736_write_pwm_buffer( addr1, g_pwm_buffer[0] ); + //IS31FL3736_write_pwm_buffer( addr2, g_pwm_buffer[1] ); + } + g_pwm_buffer_update_required = false; +} + +void IS31FL3736_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) +{ + if ( g_led_control_registers_update_required ) + { + // Firstly we need to unlock the command register and select PG0 + IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 ); + IS31FL3736_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL ); + for ( int i=0; i<24; i++ ) + { + IS31FL3736_write_register(addr1, i, g_led_control_registers[0][i] ); + //IS31FL3736_write_register(addr2, i, g_led_control_registers[1][i] ); + } + } +} + diff --git a/drivers/issi/is31fl3736.h b/drivers/issi/is31fl3736.h new file mode 100644 index 000000000..cff50fd0d --- /dev/null +++ b/drivers/issi/is31fl3736.h @@ -0,0 +1,172 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * 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 . + */ + +#pragma once + +#include +#include + + +// Simple interface option. +// If these aren't defined, just define them to make it compile + + +#ifndef DRIVER_COUNT +#define DRIVER_COUNT 2 +#endif + +#ifndef DRIVER_LED_TOTAL +#define DRIVER_LED_TOTAL 96 +#endif + + +typedef struct is31_led { + uint8_t driver:2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3736_init( uint8_t addr ); +void IS31FL3736_write_register( uint8_t addr, uint8_t reg, uint8_t data ); +void IS31FL3736_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); + +void IS31FL3736_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); +void IS31FL3736_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); + +void IS31FL3736_set_led_control_register( uint8_t index, bool red, bool green, bool blue ); + +void IS31FL3736_mono_set_brightness( int index, uint8_t value ); +void IS31FL3736_mono_set_brightness_all( uint8_t value ); +void IS31FL3736_mono_set_led_control_register( uint8_t index, bool enabled ); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3736_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ); +void IS31FL3736_update_led_control_registers( uint8_t addr1, uint8_t addr2 ); + +#define A_1 0x00 +#define A_2 0x02 +#define A_3 0x04 +#define A_4 0x06 +#define A_5 0x08 +#define A_6 0x0A +#define A_7 0x0C +#define A_8 0x0E + +#define B_1 0x10 +#define B_2 0x12 +#define B_3 0x14 +#define B_4 0x16 +#define B_5 0x18 +#define B_6 0x1A +#define B_7 0x1C +#define B_8 0x1E + +#define C_1 0x20 +#define C_2 0x22 +#define C_3 0x24 +#define C_4 0x26 +#define C_5 0x28 +#define C_6 0x2A +#define C_7 0x2C +#define C_8 0x2E + +#define D_1 0x30 +#define D_2 0x32 +#define D_3 0x34 +#define D_4 0x36 +#define D_5 0x38 +#define D_6 0x3A +#define D_7 0x3C +#define D_8 0x3E + +#define E_1 0x40 +#define E_2 0x42 +#define E_3 0x44 +#define E_4 0x46 +#define E_5 0x48 +#define E_6 0x4A +#define E_7 0x4C +#define E_8 0x4E + +#define F_1 0x50 +#define F_2 0x52 +#define F_3 0x54 +#define F_4 0x56 +#define F_5 0x58 +#define F_6 0x5A +#define F_7 0x5C +#define F_8 0x5E + +#define G_1 0x60 +#define G_2 0x62 +#define G_3 0x64 +#define G_4 0x66 +#define G_5 0x68 +#define G_6 0x6A +#define G_7 0x6C +#define G_8 0x6E + +#define H_1 0x70 +#define H_2 0x72 +#define H_3 0x74 +#define H_4 0x76 +#define H_5 0x78 +#define H_6 0x7A +#define H_7 0x7C +#define H_8 0x7E + +#define I_1 0x80 +#define I_2 0x82 +#define I_3 0x84 +#define I_4 0x86 +#define I_5 0x88 +#define I_6 0x8A +#define I_7 0x8C +#define I_8 0x8E + +#define J_1 0x90 +#define J_2 0x92 +#define J_3 0x94 +#define J_4 0x96 +#define J_5 0x98 +#define J_6 0x9A +#define J_7 0x9C +#define J_8 0x9E + +#define K_1 0xA0 +#define K_2 0xA2 +#define K_3 0xA4 +#define K_4 0xA6 +#define K_5 0xA8 +#define K_6 0xAA +#define K_7 0xAC +#define K_8 0xAE + +#define L_1 0xB0 +#define L_2 0xB2 +#define L_3 0xB4 +#define L_4 0xB6 +#define L_5 0xB8 +#define L_6 0xBA +#define L_7 0xBC +#define L_8 0xBE + -- cgit v1.2.3 From 66ef1e3d6770e388d631d25e4cd1c6b1640cea24 Mon Sep 17 00:00:00 2001 From: Wilba6582 Date: Mon, 1 Oct 2018 01:35:10 +1000 Subject: RAMA M6-B and IS31FL3218 driver (#4021) * Initial RAMA M6-B commit. * Moved IS31FL3218 driver, minor cleanups * Refactor, added dynamic keymap. * Added dynamic keymaps to RAMA M6-A * Refactor M6-A and M6-B to use common code. * Formatting * Cleanup * Cleanup * Changes from review --- drivers/issi/is31fl3218.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/issi/is31fl3218.h | 24 +++++++++++ 2 files changed, 126 insertions(+) create mode 100644 drivers/issi/is31fl3218.c create mode 100644 drivers/issi/is31fl3218.h (limited to 'drivers') diff --git a/drivers/issi/is31fl3218.c b/drivers/issi/is31fl3218.c new file mode 100644 index 000000000..db44f7256 --- /dev/null +++ b/drivers/issi/is31fl3218.c @@ -0,0 +1,102 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * 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 . + */ +#include "is31fl3218.h" +#include "i2c_master.h" + +// This is the full 8-bit address +#define ISSI_ADDRESS 0b10101000 + +// These are the register addresses +#define ISSI_REG_SHUTDOWN 0x00 +#define ISSI_REG_PWM 0x01 +#define ISSI_REG_CONTROL 0x13 +#define ISSI_REG_UPDATE 0x16 +#define ISSI_REG_RESET 0x17 + +// Default timeout if no I2C response +#define ISSI_TIMEOUT 100 + +// Reusable buffer for transfers +uint8_t g_twi_transfer_buffer[20]; + +// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining. +// If used as RGB LED driver, LEDs are assigned RGB,RGB,RGB,RGB,RGB,RGB +uint8_t g_pwm_buffer[18]; +bool g_pwm_buffer_update_required = false; + +void IS31FL3218_write_register( uint8_t reg, uint8_t data ) +{ + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + i2c_transmit( ISSI_ADDRESS, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +} + +void IS31FL3218_write_pwm_buffer( uint8_t *pwm_buffer ) +{ + g_twi_transfer_buffer[0] = ISSI_REG_PWM; + for ( int i=0; i<18; i++ ) { + g_twi_transfer_buffer[1+i] = pwm_buffer[i]; + } + + i2c_transmit( ISSI_ADDRESS, g_twi_transfer_buffer, 19, ISSI_TIMEOUT); +} + +void IS31FL3218_init(void) +{ + // In case we ever want to reinitialize (?) + IS31FL3218_write_register( ISSI_REG_RESET, 0x00 ); + + // Turn off software shutdown + IS31FL3218_write_register( ISSI_REG_SHUTDOWN, 0x01 ); + + // Set all PWM values to zero + for ( uint8_t i = 0; i < 18; i++ ) { + IS31FL3218_write_register( ISSI_REG_PWM+i, 0x00 ); + } + + // Enable all channels + for ( uint8_t i = 0; i < 3; i++ ) { + IS31FL3218_write_register( ISSI_REG_CONTROL+i, 0b00111111 ); + } + + // Load PWM registers and LED Control register data + IS31FL3218_write_register( ISSI_REG_UPDATE, 0x01 ); +} + +void IS31FL3218_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) +{ + g_pwm_buffer[index * 3 + 0] = red; + g_pwm_buffer[index * 3 + 1] = green; + g_pwm_buffer[index * 3 + 2] = blue; + g_pwm_buffer_update_required = true; +} + +void IS31FL3218_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) +{ + for ( int i = 0; i < 6; i++ ) { + IS31FL3218_set_color( i, red, green, blue ); + } +} + +void IS31FL3218_update_pwm_buffers(void) +{ + if ( g_pwm_buffer_update_required ) { + IS31FL3218_write_pwm_buffer( g_pwm_buffer ); + // Load PWM registers and LED Control register data + IS31FL3218_write_register( ISSI_REG_UPDATE, 0x01 ); + } + g_pwm_buffer_update_required = false; +} diff --git a/drivers/issi/is31fl3218.h b/drivers/issi/is31fl3218.h new file mode 100644 index 000000000..2d24e5146 --- /dev/null +++ b/drivers/issi/is31fl3218.h @@ -0,0 +1,24 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * 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 . + */ +#pragma once + +#include +#include + +void IS31FL3218_init(void); +void IS31FL3218_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); +void IS31FL3218_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); +void IS31FL3218_update_pwm_buffers(void); -- cgit v1.2.3 From 98a63d8d6e91fcd0de4e8496d21ceef17b81d5d1 Mon Sep 17 00:00:00 2001 From: yiancar Date: Mon, 8 Oct 2018 23:27:04 +0100 Subject: DC01 updates and I2C avr speed overwrite (#4088) * DC01 updates and I2C avr speed overwrite - General updating of DC01 - Made F_SCL define in AVR I2C driver overwritable from config.h * Update drivers/avr/i2c_master.c --- drivers/avr/i2c_master.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c index 47c6f8e6c..a04e6570d 100755 --- a/drivers/avr/i2c_master.c +++ b/drivers/avr/i2c_master.c @@ -8,7 +8,9 @@ #include "i2c_master.h" #include "timer.h" +#ifndef F_SCL #define F_SCL 400000UL // SCL frequency +#endif #define Prescaler 1 #define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2) -- cgit v1.2.3 From 7e99d869deb57251dc15620beff34d5fd53066e4 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Mon, 22 Oct 2018 10:26:19 -0700 Subject: Remove all of the deprecated RGB defines Fixes #3641 --- drivers/avr/ws2812.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/avr/ws2812.h b/drivers/avr/ws2812.h index f7e0c3144..1f9299ffb 100644 --- a/drivers/avr/ws2812.h +++ b/drivers/avr/ws2812.h @@ -69,7 +69,4 @@ void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask); #define CONCAT_EXP(a, b) CONCAT(a, b) #endif -// #define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port) -// #define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port) - #endif /* LIGHT_WS2812_H_ */ -- cgit v1.2.3 From 408361402385ea938575956e9368b5f373edc629 Mon Sep 17 00:00:00 2001 From: yiancar Date: Sat, 10 Nov 2018 12:26:39 -0800 Subject: I2C driver docs (#4298) * I2C driver docs - Added I2C driver docs. - Changed arm master i2c driver to have a weak i2c_init as it is impossible to account for all possible port configuration in the STM32 world. * Update docs/i2c_driver.md Co-Authored-By: yiancar * Update docs/i2c_driver.md Co-Authored-By: yiancar * Update docs/i2c_driver.md Co-Authored-By: yiancar * Update docs/i2c_driver.md Co-Authored-By: yiancar * GPIO release fix --- drivers/arm/i2c_master.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index 2a7badd35..de5843839 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c @@ -26,6 +26,7 @@ */ #include "i2c_master.h" +#include "quantum.h" #include #include @@ -41,9 +42,11 @@ static const I2CConfig i2cconfig = { 0 }; +__attribute__ ((weak)) void i2c_init(void) { - palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); // Try releasing special pins for a short time + setPinInput(B6); // Try releasing special pins for a short time + setPinInput(B7); chThdSleepMilliseconds(10); palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); -- cgit v1.2.3 From 4099536c0e7a099b181a80e483b4b95f389b5a7e Mon Sep 17 00:00:00 2001 From: ishtob Date: Tue, 4 Dec 2018 11:04:57 -0500 Subject: adding Hadron v3 keyboard, QWIIC devices support, haptic feedback support (#4462) * add initial support for hadron ver3 * add initial support for hadron ver3 * pull qwiic support for micro_led to be modified for use in hadron's 64x24 ssd1306 oled display * initial work on OLED using qwiic driver * early work to get 128x32 oled working by redefining qwiic micro oled parameters. Currently working, but would affect qwiic's micro oled functionality * moved oled defines to config.h and added ifndef to micro_oled driver * WORKING :D - note, still work in progress to get the start location correct on the 128x32 display. * added equation to automatically calculate display offset based on screen width * adding time-out timer to oled display * changed read lock staus via read_led_state * lock indications fixes * Added scroll lock indication to oled * add support for DRV2605 haptic driver * Improve readabiity of DRV2605 driver. -added typedef for waveform library -added unions for registers * Update keyboards/hadron/ver2/keymaps/default/config.h Co-Authored-By: ishtob * Update keyboards/hadron/ver2/keymaps/default/config.h Co-Authored-By: ishtob * Update keyboards/hadron/ver2/keymaps/default/config.h Co-Authored-By: ishtob * Update keyboards/hadron/ver2/keymaps/default/config.h Co-Authored-By: ishtob * Fixes for PR * PR fixes * fix old persistent layer function to use new set_single_persistent_default_layer * fix issues with changing makefile defines that broken per-key haptic pulse * Comment fixes * Add definable parameter and auto-calibration based on motor choice --- drivers/arm/i2c_master.c | 12 +- drivers/arm/i2c_master.h | 1 + drivers/haptic/DRV2605L.c | 129 ++++++++ drivers/haptic/DRV2605L.h | 394 ++++++++++++++++++++++++ drivers/qwiic/micro_oled.c | 691 ++++++++++++++++++++++++++++++++++++++++++ drivers/qwiic/micro_oled.h | 134 ++++++++ drivers/qwiic/qwiic.c | 31 ++ drivers/qwiic/qwiic.h | 28 ++ drivers/qwiic/qwiic.mk | 18 ++ drivers/qwiic/util/font5x7.h | 288 ++++++++++++++++++ drivers/qwiic/util/font8x16.h | 127 ++++++++ 11 files changed, 1849 insertions(+), 4 deletions(-) create mode 100644 drivers/haptic/DRV2605L.c create mode 100644 drivers/haptic/DRV2605L.h create mode 100644 drivers/qwiic/micro_oled.c create mode 100644 drivers/qwiic/micro_oled.h create mode 100644 drivers/qwiic/qwiic.c create mode 100644 drivers/qwiic/qwiic.h create mode 100644 drivers/qwiic/qwiic.mk create mode 100644 drivers/qwiic/util/font5x7.h create mode 100644 drivers/qwiic/util/font8x16.h (limited to 'drivers') diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index de5843839..ab962ea95 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c @@ -32,7 +32,7 @@ static uint8_t i2c_address; -// This configures the I2C clock to 400Mhz assuming a 72Mhz clock +// This configures the I2C clock to 400khz assuming a 72Mhz clock // For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html static const I2CConfig i2cconfig = { STM32_TIMINGR_PRESC(15U) | @@ -45,10 +45,14 @@ static const I2CConfig i2cconfig = { __attribute__ ((weak)) void i2c_init(void) { - setPinInput(B6); // Try releasing special pins for a short time - setPinInput(B7); - chThdSleepMilliseconds(10); + //palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); + + // Try releasing special pins for a short time + palSetPadMode(GPIOB, 6, PAL_MODE_INPUT); + palSetPadMode(GPIOB, 7, PAL_MODE_INPUT); + chThdSleepMilliseconds(10); + palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h index 591fa7f77..392760328 100644 --- a/drivers/arm/i2c_master.h +++ b/drivers/arm/i2c_master.h @@ -34,6 +34,7 @@ void i2c_init(void); uint8_t i2c_start(uint8_t address); uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); +uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout); uint8_t i2c_stop(uint16_t timeout); diff --git a/drivers/haptic/DRV2605L.c b/drivers/haptic/DRV2605L.c new file mode 100644 index 000000000..97ca292b9 --- /dev/null +++ b/drivers/haptic/DRV2605L.c @@ -0,0 +1,129 @@ +/* Copyright 2018 ishtob + * Driver for DRV2605L written for QMK + * + * 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 . + */ +#include "DRV2605L.h" +#include "print.h" +#include +#include +#include + + +uint8_t DRV2605L_transfer_buffer[20]; +uint8_t DRV2605L_tx_register[0]; +uint8_t DRV2605L_read_buffer[0]; +uint8_t DRV2605L_read_register; + + +void DRV_write(uint8_t drv_register, uint8_t settings) { + DRV2605L_transfer_buffer[0] = drv_register; + DRV2605L_transfer_buffer[1] = settings; + i2c_transmit(DRV2605L_BASE_ADDRESS << 1, DRV2605L_transfer_buffer, 2, 100); +} + +uint8_t DRV_read(uint8_t regaddress) { + DRV2605L_tx_register[0] = regaddress; + if (MSG_OK != i2c_transmit_receive(DRV2605L_BASE_ADDRESS << 1, + DRV2605L_tx_register, 1, + DRV2605L_read_buffer, 1 +)){ + printf("err reading reg \n"); + } + DRV2605L_read_register = (uint8_t)DRV2605L_read_buffer[0]; +return DRV2605L_read_register; +} + +void DRV_init(void) +{ + i2c_init(); + i2c_start(DRV2605L_BASE_ADDRESS); + + /* 0x07 sets DRV2605 into calibration mode */ + DRV_write(DRV_MODE,0x07); + +// DRV_write(DRV_FEEDBACK_CTRL,0xB6); + + #if FB_ERM_LRA == 0 + /* ERM settings */ + DRV_write(DRV_RATED_VOLT, (RATED_VOLTAGE/21.33)*1000); + #if ERM_OPEN_LOOP == 0 + DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (((V_PEAK*(DRIVE_TIME+BLANKING_TIME+IDISS_TIME))/0.02133)/(DRIVE_TIME-0.0003))); + #elif ERM_OPEN_LOOP == 1 + DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK/0.02196)); + #endif + #elif FB_ERM_LRA == 1 + DRV_write(DRV_RATED_VOLT, ((V_RMS * sqrt(1 - ((4 * ((150+(SAMPLE_TIME*50))*0.000001)) + 0.0003)* F_LRA)/0.02071))); + #if LRA_OPEN_LOOP == 0 + DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, ((V_PEAK/sqrt(1-(F_LRA*0.0008))/0.02133))); + #elif LRA_OPEN_LOOP == 1 + DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK/0.02196)); + #endif + #endif + + DRVREG_FBR FB_SET; + FB_SET.Bits.ERM_LRA = FB_ERM_LRA; + FB_SET.Bits.BRAKE_FACTOR = FB_BRAKEFACTOR; + FB_SET.Bits.LOOP_GAIN =FB_LOOPGAIN; + FB_SET.Bits.BEMF_GAIN = 0; /* auto-calibration populates this field*/ + DRV_write(DRV_FEEDBACK_CTRL, (uint8_t) FB_SET.Byte); + DRVREG_CTRL1 C1_SET; + C1_SET.Bits.C1_DRIVE_TIME = DRIVE_TIME; + C1_SET.Bits.C1_AC_COUPLE = AC_COUPLE; + C1_SET.Bits.C1_STARTUP_BOOST = STARTUP_BOOST; + DRV_write(DRV_CTRL_1, (uint8_t) C1_SET.Byte); + DRVREG_CTRL2 C2_SET; + C2_SET.Bits.C2_BIDIR_INPUT = BIDIR_INPUT; + C2_SET.Bits.C2_BRAKE_STAB = BRAKE_STAB; + C2_SET.Bits.C2_SAMPLE_TIME = SAMPLE_TIME; + C2_SET.Bits.C2_BLANKING_TIME = BLANKING_TIME; + C2_SET.Bits.C2_IDISS_TIME = IDISS_TIME; + DRV_write(DRV_CTRL_2, (uint8_t) C2_SET.Byte); + DRVREG_CTRL3 C3_SET; + C3_SET.Bits.C3_LRA_OPEN_LOOP = LRA_OPEN_LOOP; + C3_SET.Bits.C3_N_PWM_ANALOG = N_PWM_ANALOG; + C3_SET.Bits.C3_LRA_DRIVE_MODE = LRA_DRIVE_MODE; + C3_SET.Bits.C3_DATA_FORMAT_RTO = DATA_FORMAT_RTO; + C3_SET.Bits.C3_SUPPLY_COMP_DIS = SUPPLY_COMP_DIS; + C3_SET.Bits.C3_ERM_OPEN_LOOP = ERM_OPEN_LOOP; + C3_SET.Bits.C3_NG_THRESH = NG_THRESH; + DRV_write(DRV_CTRL_3, (uint8_t) C3_SET.Byte); + DRVREG_CTRL4 C4_SET; + C4_SET.Bits.C4_ZC_DET_TIME = ZC_DET_TIME; + C4_SET.Bits.C4_AUTO_CAL_TIME = AUTO_CAL_TIME; + DRV_write(DRV_CTRL_4, (uint8_t) C4_SET.Byte); + DRV_write(DRV_LIB_SELECTION,LIB_SELECTION); + //start autocalibration + DRV_write(DRV_GO, 0x01); + + /* 0x00 sets DRV2605 out of standby and to use internal trigger + * 0x01 sets DRV2605 out of standby and to use external trigger */ + DRV_write(DRV_MODE,0x00); + + /* 0x06: LRA library */ + DRV_write(DRV_WAVEFORM_SEQ_1, 0x01); + + /* 0xB9: LRA, 4x brake factor, medium gain, 7.5x back EMF + * 0x39: ERM, 4x brake factor, medium gain, 1.365x back EMF */ + + /* TODO: setup auto-calibration as part of initiation */ + +} + +void DRV_pulse(uint8_t sequence) +{ + DRV_write(DRV_GO, 0x00); + DRV_write(DRV_WAVEFORM_SEQ_1, sequence); + DRV_write(DRV_GO, 0x01); +} \ No newline at end of file diff --git a/drivers/haptic/DRV2605L.h b/drivers/haptic/DRV2605L.h new file mode 100644 index 000000000..de9d294e9 --- /dev/null +++ b/drivers/haptic/DRV2605L.h @@ -0,0 +1,394 @@ +/* Copyright 2018 ishtob + * Driver for DRV2605L written for QMK + * + * 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 . + */ + +#pragma once +#include "i2c_master.h" + +/* Initialization settings + + * Feedback Control Settings */ +#ifndef FB_ERM_LRA +#define FB_ERM_LRA 1 /* For ERM:0 or LRA:1*/ +#endif +#ifndef FB_BRAKEFACTOR +#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ +#endif +#ifndef FB_LOOPGAIN +#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ +#endif + +#ifndef RATED_VOLTAGE +#define RATED_VOLTAGE 2 /* 2v as safe range in case device voltage is not set */ +#ifndef V_PEAK +#define V_PEAK 2.8 +#endif +#endif + +/* LRA specific settings */ +#if FB_ERM_LRA == 1 +#ifndef V_RMS +#define V_RMS 2.0 +#endif +#ifndef V_PEAK +#define V_PEAK 2.1 +#endif +#ifndef F_LRA +#define F_LRA 205 +#endif +#endif + +/* Library Selection */ +#ifndef LIB_SELECTION +#if FB_ERM_LRA == 1 +#define LIB_SELECTION 6 /* For Empty:0' TS2200 library A to D:1-5, LRA Library: 6 */ +#else +#define LIB_SELECTION 1 +#endif +#endif + +/* Control 1 register settings */ +#ifndef DRIVE_TIME +#define DRIVE_TIME 25 +#endif +#ifndef AC_COUPLE +#define AC_COUPLE 0 +#endif +#ifndef STARTUP_BOOST +#define STARTUP_BOOST 1 +#endif + +/* Control 2 Settings */ +#ifndef BIDIR_INPUT +#define BIDIR_INPUT 1 +#endif +#ifndef BRAKE_STAB +#define BRAKE_STAB 1 /* Loopgain is reduced when braking is almost complete to improve stability */ +#endif +#ifndef SAMPLE_TIME +#define SAMPLE_TIME 3 +#endif +#ifndef BLANKING_TIME +#define BLANKING_TIME 1 +#endif +#ifndef IDISS_TIME +#define IDISS_TIME 1 +#endif + +/* Control 3 settings */ +#ifndef NG_THRESH +#define NG_THRESH 2 +#endif +#ifndef ERM_OPEN_LOOP +#define ERM_OPEN_LOOP 1 +#endif +#ifndef SUPPLY_COMP_DIS +#define SUPPLY_COMP_DIS 0 +#endif +#ifndef DATA_FORMAT_RTO +#define DATA_FORMAT_RTO 0 +#endif +#ifndef LRA_DRIVE_MODE +#define LRA_DRIVE_MODE 0 +#endif +#ifndef N_PWM_ANALOG +#define N_PWM_ANALOG 0 +#endif +#ifndef LRA_OPEN_LOOP +#define LRA_OPEN_LOOP 0 +#endif + +/* Control 4 settings */ +#ifndef ZC_DET_TIME +#define ZC_DET_TIME 0 +#endif +#ifndef AUTO_CAL_TIME +#define AUTO_CAL_TIME 3 +#endif + +/* register defines -------------------------------------------------------- */ +#define DRV2605L_BASE_ADDRESS 0x5A /* DRV2605L Base address */ +#define DRV_STATUS 0x00 +#define DRV_MODE 0x01 +#define DRV_RTP_INPUT 0x02 +#define DRV_LIB_SELECTION 0x03 +#define DRV_WAVEFORM_SEQ_1 0x04 +#define DRV_WAVEFORM_SEQ_2 0x05 +#define DRV_WAVEFORM_SEQ_3 0x06 +#define DRV_WAVEFORM_SEQ_4 0x07 +#define DRV_WAVEFORM_SEQ_5 0x08 +#define DRV_WAVEFORM_SEQ_6 0x09 +#define DRV_WAVEFORM_SEQ_7 0x0A +#define DRV_WAVEFORM_SEQ_8 0x0B +#define DRV_GO 0x0C +#define DRV_OVERDRIVE_TIME_OFFSET 0x0D +#define DRV_SUSTAIN_TIME_OFFSET_P 0x0E +#define DRV_SUSTAIN_TIME_OFFSET_N 0x0F +#define DRV_BRAKE_TIME_OFFSET 0x10 +#define DRV_AUDIO_2_VIBE_CTRL 0x11 +#define DRV_AUDIO_2_VIBE_MIN_IN 0x12 +#define DRV_AUDIO_2_VIBE_MAX_IN 0x13 +#define DRV_AUDIO_2_VIBE_MIN_OUTDRV 0x14 +#define DRV_AUDIO_2_VIBE_MAX_OUTDRV 0x15 +#define DRV_RATED_VOLT 0x16 +#define DRV_OVERDRIVE_CLAMP_VOLT 0x17 +#define DRV_AUTO_CALIB_COMP_RESULT 0x18 +#define DRV_AUTO_CALIB_BEMF_RESULT 0x19 +#define DRV_FEEDBACK_CTRL 0x1A +#define DRV_CTRL_1 0x1B +#define DRV_CTRL_2 0x1C +#define DRV_CTRL_3 0x1D +#define DRV_CTRL_4 0x1E +#define DRV_CTRL_5 0x1F +#define DRV_OPEN_LOOP_PERIOD 0x20 +#define DRV_VBAT_VOLT_MONITOR 0x21 +#define DRV_LRA_RESONANCE_PERIOD 0x22 + +void DRV_init(void); +void DRV_write(const uint8_t drv_register, const uint8_t settings); +uint8_t DRV_read(const uint8_t regaddress); +void DRV_pulse(const uint8_t sequence); + + +typedef enum DRV_EFFECT{ + clear_sequence = 0, + strong_click = 1, + strong_click_60 = 2, + strong_click_30 = 3, + sharp_click = 4, + sharp_click_60 = 5, + sharp_click_30 = 6, + soft_bump = 7, + soft_bump_60 = 8, + soft_bump_30 = 9, + dbl_click = 10, + dbl_click_60 = 11, + trp_click = 12, + soft_fuzz = 13, + strong_buzz = 14, + alert_750ms = 15, + alert_1000ms = 16, + strong_click1 = 17, + strong_click2_80 = 18, + strong_click3_60 = 19, + strong_click4_30 = 20, + medium_click1 = 21, + medium_click2_80 = 22, + medium_click3_60 = 23, + sharp_tick1 = 24, + sharp_tick2_80 = 25, + sharp_tick3_60 = 26, + sh_dblclick_str = 27, + sh_dblclick_str_80 = 28, + sh_dblclick_str_60 = 29, + sh_dblclick_str_30 = 30, + sh_dblclick_med = 31, + sh_dblclick_med_80 = 32, + sh_dblclick_med_60 = 33, + sh_dblsharp_tick = 34, + sh_dblsharp_tick_80 = 35, + sh_dblsharp_tick_60 = 36, + lg_dblclick_str = 37, + lg_dblclick_str_80 = 38, + lg_dblclick_str_60 = 39, + lg_dblclick_str_30 = 40, + lg_dblclick_med = 41, + lg_dblclick_med_80 = 42, + lg_dblclick_med_60 = 43, + lg_dblsharp_tick = 44, + lg_dblsharp_tick_80 = 45, + lg_dblsharp_tick_60 = 46, + buzz = 47, + buzz_80 = 48, + buzz_60 = 49, + buzz_40 = 50, + buzz_20 = 51, + pulsing_strong = 52, + pulsing_strong_80 = 53, + pulsing_medium = 54, + pulsing_medium_80 = 55, + pulsing_sharp = 56, + pulsing_sharp_80 = 57, + transition_click = 58, + transition_click_80 = 59, + transition_click_60 = 60, + transition_click_40 = 61, + transition_click_20 = 62, + transition_click_10 = 63, + transition_hum = 64, + transition_hum_80 = 65, + transition_hum_60 = 66, + transition_hum_40 = 67, + transition_hum_20 = 68, + transition_hum_10 = 69, + transition_rampdown_long_smooth1 = 70, + transition_rampdown_long_smooth2 = 71, + transition_rampdown_med_smooth1 = 72, + transition_rampdown_med_smooth2 = 73, + transition_rampdown_short_smooth1 = 74, + transition_rampdown_short_smooth2 = 75, + transition_rampdown_long_sharp1 = 76, + transition_rampdown_long_sharp2 = 77, + transition_rampdown_med_sharp1 = 78, + transition_rampdown_med_sharp2 = 79, + transition_rampdown_short_sharp1 = 80, + transition_rampdown_short_sharp2 = 81, + transition_rampup_long_smooth1 = 82, + transition_rampup_long_smooth2 = 83, + transition_rampup_med_smooth1 = 84, + transition_rampup_med_smooth2 = 85, + transition_rampup_short_smooth1 = 86, + transition_rampup_short_smooth2 = 87, + transition_rampup_long_sharp1 = 88, + transition_rampup_long_sharp2 = 89, + transition_rampup_med_sharp1 = 90, + transition_rampup_med_sharp2 = 91, + transition_rampup_short_sharp1 = 92, + transition_rampup_short_sharp2 = 93, + transition_rampdown_long_smooth1_50 = 94, + transition_rampdown_long_smooth2_50 = 95, + transition_rampdown_med_smooth1_50 = 96, + transition_rampdown_med_smooth2_50 = 97, + transition_rampdown_short_smooth1_50 = 98, + transition_rampdown_short_smooth2_50 = 99, + transition_rampdown_long_sharp1_50 = 100, + transition_rampdown_long_sharp2_50 = 101, + transition_rampdown_med_sharp1_50 = 102, + transition_rampdown_med_sharp2_50 = 103, + transition_rampdown_short_sharp1_50 = 104, + transition_rampdown_short_sharp2_50 = 105, + transition_rampup_long_smooth1_50 = 106, + transition_rampup_long_smooth2_50 = 107, + transition_rampup_med_smooth1_50 = 108, + transition_rampup_med_smooth2_50 = 109, + transition_rampup_short_smooth1_50 = 110, + transition_rampup_short_smooth2_50 = 111, + transition_rampup_long_sharp1_50 = 112, + transition_rampup_long_sharp2_50 = 113, + transition_rampup_med_sharp1_50 = 114, + transition_rampup_med_sharp2_50 = 115, + transition_rampup_short_sharp1_50 = 116, + transition_rampup_short_sharp2_50 = 117, + long_buzz_for_programmatic_stopping = 118, + smooth_hum1_50 = 119, + smooth_hum2_40 = 120, + smooth_hum3_30 = 121, + smooth_hum4_20 = 122, + smooth_hum5_10 = 123, +} DRV_EFFECT; + +/* Register bit array unions */ + +typedef union DRVREG_STATUS { /* register 0x00 */ + uint8_t Byte; + struct { + uint8_t OC_DETECT :1; /* set to 1 when overcurrent event is detected */ + uint8_t OVER_TEMP :1; /* set to 1 when device exceeds temp threshold */ + uint8_t FB_STS :1; /* set to 1 when feedback controller has timed out */ + /* auto-calibration routine and diagnostic result + * result | auto-calibation | diagnostic | + * 0 | passed | actuator func normal | + * 1 | failed | actuator func fault* | + * * actuator is not present or is shorted, timing out, or giving out–of-range back-EMF */ + uint8_t DIAG_RESULT :1; + uint8_t :1; + uint8_t DEVICE_ID :3; /* Device IDs 3: DRV2605 4: DRV2604 5: DRV2604L 6: DRV2605L */ + } Bits; +} DRVREG_STATUS; + +typedef union DRVREG_MODE { /* register 0x01 */ + uint8_t Byte; + struct { + uint8_t MODE :3; /* Mode setting */ + uint8_t :3; + uint8_t STANDBY :1; /* 0:standby 1:ready */ + } Bits; +} DRVREG_MODE; + +typedef union DRVREG_WAIT { + uint8_t Byte; + struct { + uint8_t WAIT_MODE :1; /* Set to 1 to interpret as wait for next 7 bits x10ms */ + uint8_t WAIT_TIME :7; + } Bits; +} DRVREG_WAIT; + +typedef union DRVREG_FBR{ /* register 0x1A */ + uint8_t Byte; + struct { + uint8_t BEMF_GAIN :2; + uint8_t LOOP_GAIN :2; + uint8_t BRAKE_FACTOR :3; + uint8_t ERM_LRA :1; + } Bits; +} DRVREG_FBR; + +typedef union DRVREG_CTRL1{ /* register 0x1B */ + uint8_t Byte; + struct { + uint8_t C1_DRIVE_TIME :5; + uint8_t C1_AC_COUPLE :1; + uint8_t :1; + uint8_t C1_STARTUP_BOOST :1; + } Bits; +} DRVREG_CTRL1; + +typedef union DRVREG_CTRL2{ /* register 0x1C */ + uint8_t Byte; + struct { + uint8_t C2_IDISS_TIME :2; + uint8_t C2_BLANKING_TIME :2; + uint8_t C2_SAMPLE_TIME :2; + uint8_t C2_BRAKE_STAB :1; + uint8_t C2_BIDIR_INPUT :1; + } Bits; +} DRVREG_CTRL2; + +typedef union DRVREG_CTRL3{ /* register 0x1D */ + uint8_t Byte; + struct { + uint8_t C3_LRA_OPEN_LOOP :1; + uint8_t C3_N_PWM_ANALOG :1; + uint8_t C3_LRA_DRIVE_MODE :1; + uint8_t C3_DATA_FORMAT_RTO :1; + uint8_t C3_SUPPLY_COMP_DIS :1; + uint8_t C3_ERM_OPEN_LOOP :1; + uint8_t C3_NG_THRESH :2; + } Bits; +} DRVREG_CTRL3; + +typedef union DRVREG_CTRL4{ /* register 0x1E */ + uint8_t Byte; + struct { + uint8_t C4_OTP_PROGRAM :1; + uint8_t :1; + uint8_t C4_OTP_STATUS :1; + uint8_t :1; + uint8_t C4_AUTO_CAL_TIME :2; + uint8_t C4_ZC_DET_TIME :2; + } Bits; +} DRVREG_CTRL4; + +typedef union DRVREG_CTRL5{ /* register 0x1F */ + uint8_t Byte; + struct { + uint8_t C5_IDISS_TIME :2; + uint8_t C5_BLANKING_TIME :2; + uint8_t C5_PLAYBACK_INTERVAL :1; + uint8_t C5_LRA_AUTO_OPEN_LOOP :1; + uint8_t C5_AUTO_OL_CNT :2; + } Bits; +} DRVREG_CTRL5; \ No newline at end of file diff --git a/drivers/qwiic/micro_oled.c b/drivers/qwiic/micro_oled.c new file mode 100644 index 000000000..35c5d6ee1 --- /dev/null +++ b/drivers/qwiic/micro_oled.c @@ -0,0 +1,691 @@ +/* Jim Lindblom @ SparkFun Electronics + * October 26, 2014 + * https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED + * + * Modified by: + * Emil Varughese @ Edwin Robotics Pvt. Ltd. + * July 27, 2015 + * https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ + * + * This code was heavily based around the MicroView library, written by GeekAmmo + * (https://github.com/geekammo/MicroView-Arduino-Library). + * + * Adapted for QMK by: + * Jack Humbert + * October 11, 2018 + * + * 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 3 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 . + */ +#include "micro_oled.h" +#include +#include "util/font5x7.h" +#include "util/font8x16.h" +#include "string.h" + +#define TOTALFONTS 2 +const unsigned char * fonts_pointer[]= { font5x7, font8x16 }; + +uint8_t foreColor,drawMode,fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY; +uint16_t fontMapWidth; + +#define _BV(x) (1 << (x)) +#define swap(a, b) { uint8_t t = a; a = b; b = t; } + +uint8_t micro_oled_transfer_buffer[20]; +static uint8_t micro_oled_screen_current[LCDWIDTH*LCDWIDTH/8] = { 0 }; + +/* LCD Memory organised in 64 horizontal pixel and 6 rows of byte + B B .............B ----- + y y .............y \ + t t .............t \ + e e .............e \ + 0 1 .............63 \ + \ + D0 D0.............D0 \ + D1 D1.............D1 / ROW 0 + D2 D2.............D2 / + D3 D3.............D3 / + D4 D4.............D4 / + D5 D5.............D5 / + D6 D6.............D6 / + D7 D7.............D7 ---- + */ + +#if LCDWIDTH == 64 + #if LCDWIDTH == 48 +static uint8_t micro_oled_screen_buffer[] = { +// QMK Logo - generated at http://www.majer.ch/lcd/adf_bitmap.php +//64x48 image +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, +0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, +0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, +0xF8, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, +0xFE, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x8C, 0x8C, 0x8C, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, +0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8C, 0x8C, 0x8C, 0x8C, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF1, 0xE3, 0xE7, 0xCF, +0xCF, 0xCF, 0xCF, 0x00, 0x00, 0xCF, 0xCF, 0xCF, 0xC7, 0xE7, +0xE3, 0xF1, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x31, 0x31, 0x31, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, +0x06, 0x06, 0x1F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0x7F, 0x7F, 0x1F, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, +0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, +0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00 +}; + #endif +#elif LCDWIDTH == 128 + #if LCDHEIGHT == 32 + static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = { +//128x32 qmk image +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xFC, 0xFC, +0xE0, 0xF0, 0xFC, 0xE0, 0xE0, 0xFC, 0xE0, 0xE0, 0xFC, 0xFC, +0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x30, 0xE0, 0x00, 0x00, +0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, +0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, +0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, +0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, +0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xB2, 0xB2, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0x03, +0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, +0xFF, 0xB7, 0xB2, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x1F, 0x02, 0x02, 0x03, 0x01, 0x00, 0x06, 0x1F, 0x10, +0x10, 0x10, 0x1F, 0x06, 0x00, 0x03, 0x1E, 0x18, 0x0F, 0x01, +0x0F, 0x18, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x12, 0x02, 0x12, +0x13, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0x12, +0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x1F, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x48, 0x4D, 0x4D, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFE, 0xF8, 0xF9, 0xF3, 0xF3, 0xC0, 0x80, 0xF3, +0xF3, 0xF3, 0xF9, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED, +0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0xC0, 0x00, 0x70, 0xC0, +0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0C, +0x04, 0x04, 0x04, 0x04, 0x1C, 0xF0, 0x00, 0x00, 0xFC, 0x0C, +0x38, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x0C, 0xFC, 0x00, 0x00, +0xFC, 0xFC, 0x60, 0x90, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x3F, +0x3F, 0x07, 0x3F, 0x3F, 0x07, 0x0F, 0x3F, 0x07, 0x07, 0x3F, +0x07, 0x07, 0x3F, 0x3F, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, +0x06, 0x04, 0x04, 0x07, 0x01, 0x00, 0x00, 0x13, 0x1E, 0x03, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x04, +0x04, 0x04, 0x07, 0x0D, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01, +0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07, +0x00, 0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00 + }; + #elif LCDHEIGHT == 64 + static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, +0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, +0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, +0x7F, 0x7E, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7F, 0xFE, +0xFE, 0xFF, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC, +0xFC, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x88, 0x88, 0x88, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xDD, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF3, 0xF3, 0xE7, 0xE7, 0x00, +0x00, 0xE7, 0xE7, 0xF3, 0xF3, 0xF0, 0xF8, 0xFE, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x1F, 0x3F, +0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, +0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, +0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, +0x80, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x00, 0x80, 0x01, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x70, +0x88, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x00, 0x3C, 0xE0, 0xC0, +0x38, 0x1C, 0xE0, 0x80, 0x70, 0x0C, 0x00, 0xF8, 0xAC, 0x24, +0x24, 0x3C, 0x30, 0x00, 0x00, 0xFC, 0x0C, 0x04, 0x00, 0xF8, +0xAC, 0x24, 0x24, 0x2C, 0x30, 0x00, 0x70, 0xDC, 0x04, 0x04, +0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, +0x8C, 0x04, 0x04, 0xF8, 0x00, 0x04, 0x3C, 0xE0, 0x80, 0xF0, +0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x83, 0x01, 0x01, +0x01, 0x81, 0xFE, 0x3C, 0x00, 0x00, 0xFF, 0x03, 0x0E, 0x70, +0xC0, 0xE0, 0x38, 0x06, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x18, +0x38, 0x66, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, +0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, +0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; +//TODO: generate bitmap of QMK logo here + #endif +#else +//catchall for custom screen szies + static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = {0}; +#endif + + + +void micro_oled_init(void) { + + i2c_init(); + i2c_start(I2C_ADDRESS_SA0_1); + + // Display Init sequence for 64x48 OLED module + send_command(DISPLAYOFF); // 0xAE + + send_command(SETDISPLAYCLOCKDIV); // 0xD5 + send_command(0x80); // the suggested ratio 0x80 + + send_command(SETMULTIPLEX); // 0xA8 + send_command(LCDHEIGHT - 1); + + send_command(SETDISPLAYOFFSET); // 0xD3 + send_command(0x00); // no offset + + send_command(SETSTARTLINE | 0x00); // line #0 + + send_command(CHARGEPUMP); // enable charge pump + send_command(0x14); + + send_command(NORMALDISPLAY); // 0xA6 + send_command(DISPLAYALLONRESUME); // 0xA4 + +//display at regular orientation + send_command(SEGREMAP | 0x1); + send_command(COMSCANDEC); + +//rotate display 180 +#ifdef micro_oled_rotate_180 + send_command(SEGREMAP); + send_command(COMSCANINC); +#endif + + send_command(MEMORYMODE); + send_command(0x10); + + send_command(SETCOMPINS); // 0xDA +if (LCDHEIGHT > 32) { + send_command(0x12); +} else { + send_command(0x02); +} + send_command(SETCONTRAST); // 0x81 + send_command(0x8F); + + send_command(SETPRECHARGE); // 0xd9 + send_command(0xF1); + + send_command(SETVCOMDESELECT); // 0xDB + send_command(0x40); + + send_command(DISPLAYON); //--turn on oled panel + clear_screen(); // Erase hardware memory inside the OLED controller to avoid random data in memory. + send_buffer(); +} + +void send_command(uint8_t command) { + micro_oled_transfer_buffer[0] = I2C_COMMAND; + micro_oled_transfer_buffer[1] = command; + i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); +} + +void send_data(uint8_t data) { + micro_oled_transfer_buffer[0] = I2C_DATA; + micro_oled_transfer_buffer[1] = data; + i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100); +} + +/** \brief Set SSD1306 page address. + Send page address command and address to the SSD1306 OLED controller. +*/ +void set_page_address(uint8_t address) { + address = (0xB0 | address); + send_command(address); +} + +/** \brief Set SSD1306 column address. + Send column address command and address to the SSD1306 OLED controller. +*/ +void set_column_address(uint8_t address) { + send_command( ( 0x10 | (address >> 4) ) + ((128 - LCDWIDTH) >> 8) ); + send_command( 0x0F & address ); +} + +/** \brief Clear SSD1306's memory. + To clear GDRAM inside the LCD controller. +*/ +void clear_screen(void) { + for (int i=0;i<8; i++) { + set_page_address(i); + set_column_address(0); + for (int j=0; j<0x80; j++) { + send_data(0); + } + } +} + +/** \brief Clear SSD1306's memory. + To clear GDRAM inside the LCD controller. +*/ +void clear_buffer(void) { +//384 + memset(micro_oled_screen_buffer, 0, LCDWIDTH*LCDWIDTH/8); +} + +/** \brief Invert display. + The PIXEL_ON color of the display will turn to PIXEL_OFF and the PIXEL_OFF will turn to PIXEL_ON. +*/ +void invert_screen(bool invert) { + if (invert) { + send_command(INVERTDISPLAY); + } else { + send_command(NORMALDISPLAY); + } +} + +/** \brief Set contrast. + OLED contract value from 0 to 255. Note: Contrast level is not very obvious. +*/ +void set_contrast(uint8_t contrast) { + send_command(SETCONTRAST); // 0x81 + send_command(contrast); +} + +/** \brief Transfer display buffer. + Sends the updated buffer to the controller - the current status is checked before to save i2c exectution time +*/ +void send_buffer(void) { + uint8_t i, j; + + uint8_t page_addr = 0xFF; + for (i = 0; i < LCDHEIGHT/8; i++) { + uint8_t col_addr = 0xFF; + for (j = 0; j < LCDWIDTH; j++) { + if (micro_oled_screen_buffer[i*LCDWIDTH+j] != micro_oled_screen_current[i*LCDWIDTH+j]) { + if (page_addr != i) { + set_page_address(i); + } + if (col_addr != j) { + set_column_address(j); + } + send_data(micro_oled_screen_buffer[i*LCDWIDTH+j]); + micro_oled_screen_current[i*LCDWIDTH+j] = micro_oled_screen_buffer[i*LCDWIDTH+j]; + col_addr = j + 1; + } + } + } +} + +/** \brief Draw pixel with color and mode. + Draw color pixel in the screen buffer's x,y position with NORM or XOR draw mode. +*/ +void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode) { + if ((x<0) || (x>=LCDWIDTH) || (y<0) || (y>=LCDHEIGHT)) + return; + + if (mode == XOR) { + if (color == PIXEL_ON) + micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] ^= _BV((y%8)); + } else { + if (color == PIXEL_ON) + micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] |= _BV((y%8)); + else + micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] &= ~_BV((y%8)); + } +} + +/** \brief Draw line with color and mode. +Draw line using color and mode from x0,y0 to x1,y1 of the screen buffer. +*/ +void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode) { + uint8_t steep = abs(y1 - y0) > abs(x1 - x0); + if (steep) { + swap(x0, y0); + swap(x1, y1); + } + + if (x0 > x1) { + swap(x0, x1); + swap(y0, y1); + } + + uint8_t dx, dy; + dx = x1 - x0; + dy = abs(y1 - y0); + + int8_t err = dx / 2; + int8_t ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1;} + + for (; x0=TOTALFONTS) || (font<0)) + return; + + uint8_t fontType = font; + uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType]+0); + uint8_t fontHeight = pgm_read_byte(fonts_pointer[fontType]+1); + uint8_t fontStartChar = pgm_read_byte(fonts_pointer[fontType]+2); + uint8_t fontTotalChar = pgm_read_byte(fonts_pointer[fontType]+3); + uint16_t fontMapWidth = (pgm_read_byte(fonts_pointer[fontType]+4)*100)+pgm_read_byte(fonts_pointer[fontType]+5); // two bytes values into integer 16 + + if ((c(fontStartChar+fontTotalChar-1))) // no bitmap for the required c + return; + + tempC=c-fontStartChar; + + // each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn + rowsToDraw=fontHeight/8; // 8 is LCD's page size, see SSD1306 datasheet + if (rowsToDraw<=1) rowsToDraw=1; + + // the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw + if (rowsToDraw==1) { + for (i=0;i>=1; + } + } + return; + } + + // font height over 8 bit + // take character "0" ASCII 48 as example + charPerBitmapRow = fontMapWidth/fontWidth; // 256/8 =32 char per row + charColPositionOnBitmap = tempC % charPerBitmapRow; // =16 + charRowPositionOnBitmap = (int)(tempC/charPerBitmapRow); // =1 + charBitmapStartPosition = (charRowPositionOnBitmap * fontMapWidth * (fontHeight/8)) + (charColPositionOnBitmap * fontWidth) ; + + // each row on LCD is 8 bit height (see datasheet for explanation) + for(row=0;row>=1; + } + } + } + +} + +void draw_string(uint8_t x, uint8_t y, char * string, uint8_t color, uint8_t mode, uint8_t font) { + + if ((font>=TOTALFONTS) || (font<0)) + return; + + uint8_t fontType = font; + uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType]+0); + + uint8_t cur_x = x; + for (int i = 0; i < strlen(string); i++) { + draw_char(cur_x, y, string[i], color, mode, font); + cur_x += fontWidth + 1; + } + +} diff --git a/drivers/qwiic/micro_oled.h b/drivers/qwiic/micro_oled.h new file mode 100644 index 000000000..5d6a1029e --- /dev/null +++ b/drivers/qwiic/micro_oled.h @@ -0,0 +1,134 @@ +/* Jim Lindblom @ SparkFun Electronics + * October 26, 2014 + * https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED + * + * Modified by: + * Emil Varughese @ Edwin Robotics Pvt. Ltd. + * July 27, 2015 + * https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ + * + * This code was heavily based around the MicroView library, written by GeekAmmo + * (https://github.com/geekammo/MicroView-Arduino-Library). + * + * Adapted for QMK by: + * Jack Humbert + * October 11, 2018 + * + * 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 3 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 . + */ +#pragma once + +#include "qwiic.h" + +void micro_oled_init(void); + +void send_command(uint8_t command); +void send_data(uint8_t data); +void set_page_address(uint8_t address); +void set_column_address(uint8_t address); +void clear_screen(void); +void clear_buffer(void); +void send_buffer(void); +void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode); +void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode); +void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode); +void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode); +void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); +void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); +void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); +void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode); +void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font); +void draw_string(uint8_t x, uint8_t y, char * string, uint8_t color, uint8_t mode, uint8_t font); + +#define I2C_ADDRESS_SA0_0 0b0111100 +#ifndef I2C_ADDRESS_SA0_1 +#define I2C_ADDRESS_SA0_1 0b0111101 +#endif +#define I2C_COMMAND 0x00 +#define I2C_DATA 0x40 +#define PIXEL_OFF 0 +#define PIXEL_ON 1 + +#ifndef LCDWIDTH +#define LCDWIDTH 64 +#endif +#ifndef LCDWIDTH +#define LCDHEIGHT 48 +#endif +#define FONTHEADERSIZE 6 + +#define NORM 0 +#define XOR 1 + +#define PAGE 0 +#define ALL 1 + +#define WIDGETSTYLE0 0 +#define WIDGETSTYLE1 1 +#define WIDGETSTYLE2 2 + +#define SETCONTRAST 0x81 +#define DISPLAYALLONRESUME 0xA4 +#define DISPLAYALLON 0xA5 +#define NORMALDISPLAY 0xA6 +#define INVERTDISPLAY 0xA7 +#define DISPLAYOFF 0xAE +#define DISPLAYON 0xAF +#define SETDISPLAYOFFSET 0xD3 +#define SETCOMPINS 0xDA +#define SETVCOMDESELECT 0xDB +#define SETDISPLAYCLOCKDIV 0xD5 +#define SETPRECHARGE 0xD9 +#define SETMULTIPLEX 0xA8 +#define SETLOWCOLUMN 0x00 +#define SETHIGHCOLUMN 0x10 +#define SETSTARTLINE 0x40 +#define MEMORYMODE 0x20 +#define COMSCANINC 0xC0 +#define COMSCANDEC 0xC8 +#define SEGREMAP 0xA0 +#define CHARGEPUMP 0x8D +#define EXTERNALVCC 0x01 +#define SWITCHCAPVCC 0x02 + +// Scroll +#define ACTIVATESCROLL 0x2F +#define DEACTIVATESCROLL 0x2E +#define SETVERTICALSCROLLAREA 0xA3 +#define RIGHTHORIZONTALSCROLL 0x26 +#define LEFT_HORIZONTALSCROLL 0x27 +#define VERTICALRIGHTHORIZONTALSCROLL 0x29 +#define VERTICALLEFTHORIZONTALSCROLL 0x2A + +typedef enum CMD { + CMD_CLEAR, //0 + CMD_INVERT, //1 + CMD_CONTRAST, //2 + CMD_DISPLAY, //3 + CMD_SETCURSOR, //4 + CMD_PIXEL, //5 + CMD_LINE, //6 + CMD_LINEH, //7 + CMD_LINEV, //8 + CMD_RECT, //9 + CMD_RECTFILL, //10 + CMD_CIRCLE, //11 + CMD_CIRCLEFILL, //12 + CMD_DRAWCHAR, //13 + CMD_DRAWBITMAP, //14 + CMD_GETLCDWIDTH, //15 + CMD_GETLCDHEIGHT, //16 + CMD_SETCOLOR, //17 + CMD_SETDRAWMODE //18 +} commCommand_t; \ No newline at end of file diff --git a/drivers/qwiic/qwiic.c b/drivers/qwiic/qwiic.c new file mode 100644 index 000000000..904791992 --- /dev/null +++ b/drivers/qwiic/qwiic.c @@ -0,0 +1,31 @@ +/* Copyright 2018 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 . + */ +#include "qwiic.h" + +void qwiic_init(void) { + #ifdef QWIIC_JOYSTIIC_ENABLE + joystiic_init(); + #endif + #ifdef QWIIC_MICRO_OLED_ENABLE + micro_oled_init(); + #endif +} + +void qwiic_task(void) { + #ifdef QWIIC_JOYSTIIC_ENABLE + joystiic_task(); + #endif +} diff --git a/drivers/qwiic/qwiic.h b/drivers/qwiic/qwiic.h new file mode 100644 index 000000000..160fb28df --- /dev/null +++ b/drivers/qwiic/qwiic.h @@ -0,0 +1,28 @@ +/* Copyright 2018 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 . + */ +#pragma once + +#include "i2c_master.h" + +#ifdef QWIIC_JOYSTIIC_ENABLE + #include "joystiic.h" +#endif +#ifdef QWIIC_MICRO_OLED_ENABLE + #include "micro_oled.h" +#endif + +void qwiic_init(void); +void qwiic_task(void); diff --git a/drivers/qwiic/qwiic.mk b/drivers/qwiic/qwiic.mk new file mode 100644 index 000000000..4ae2d78e3 --- /dev/null +++ b/drivers/qwiic/qwiic.mk @@ -0,0 +1,18 @@ +ifneq ($(strip $(QWIIC_ENABLE)),) + COMMON_VPATH += $(DRIVER_PATH)/qwiic + OPT_DEFS += -DQWIIC_ENABLE + SRC += qwiic.c + ifeq ($(filter "i2c_master.c", $(SRC)),) + SRC += i2c_master.c + endif +endif + +ifneq ($(filter JOYSTIIC, $(QWIIC_ENABLE)),) + OPT_DEFS += -DQWIIC_JOYSTIIC_ENABLE + SRC += joystiic.c +endif + +ifneq ($(filter MICRO_OLED, $(QWIIC_ENABLE)),) + OPT_DEFS += -DQWIIC_MICRO_OLED_ENABLE + SRC += micro_oled.c +endif diff --git a/drivers/qwiic/util/font5x7.h b/drivers/qwiic/util/font5x7.h new file mode 100644 index 000000000..0bad206b7 --- /dev/null +++ b/drivers/qwiic/util/font5x7.h @@ -0,0 +1,288 @@ +/****************************************************************************** +font5x7.h +Definition for small font + +This file was imported from the MicroView library, written by GeekAmmo +(https://github.com/geekammo/MicroView-Arduino-Library), and released under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 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 . + +Modified by: +Emil Varughese @ Edwin Robotics Pvt. Ltd. +July 27, 2015 +https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ + +******************************************************************************/ +#pragma once + +#include "progmem.h" + +// Standard ASCII 5x7 font +static const unsigned char font5x7[] PROGMEM = { + // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256) + 5,8,0,255,12,75, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, + 0x00, 0x18, 0x3C, 0x18, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, + 0x00, 0x18, 0x24, 0x18, 0x00, + 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, + 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, + 0x40, 0x7F, 0x05, 0x05, 0x07, + 0x40, 0x7F, 0x05, 0x25, 0x3F, + 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, + 0x14, 0x22, 0x7F, 0x22, 0x14, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, + 0x06, 0x09, 0x7F, 0x01, 0x7F, + 0x00, 0x66, 0x89, 0x95, 0x6A, + 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, + 0x08, 0x04, 0x7E, 0x04, 0x08, + 0x10, 0x20, 0x7E, 0x20, 0x10, + 0x08, 0x08, 0x2A, 0x1C, 0x08, + 0x08, 0x1C, 0x2A, 0x08, 0x08, + 0x1E, 0x10, 0x10, 0x10, 0x10, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, + 0x30, 0x38, 0x3E, 0x38, 0x30, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, + 0x36, 0x49, 0x56, 0x20, 0x50, + 0x00, 0x08, 0x07, 0x03, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, + 0x08, 0x08, 0x3E, 0x08, 0x08, + 0x00, 0x80, 0x70, 0x30, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x60, 0x60, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, + 0x00, 0x42, 0x7F, 0x40, 0x00, + 0x72, 0x49, 0x49, 0x49, 0x46, + 0x21, 0x41, 0x49, 0x4D, 0x33, + 0x18, 0x14, 0x12, 0x7F, 0x10, + 0x27, 0x45, 0x45, 0x45, 0x39, + 0x3C, 0x4A, 0x49, 0x49, 0x31, + 0x41, 0x21, 0x11, 0x09, 0x07, + 0x36, 0x49, 0x49, 0x49, 0x36, + 0x46, 0x49, 0x49, 0x29, 0x1E, + 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x00, 0x41, 0x22, 0x14, 0x08, + 0x02, 0x01, 0x59, 0x09, 0x06, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, + 0x7C, 0x12, 0x11, 0x12, 0x7C, + 0x7F, 0x49, 0x49, 0x49, 0x36, + 0x3E, 0x41, 0x41, 0x41, 0x22, + 0x7F, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x49, 0x49, 0x49, 0x41, + 0x7F, 0x09, 0x09, 0x09, 0x01, + 0x3E, 0x41, 0x41, 0x51, 0x73, + 0x7F, 0x08, 0x08, 0x08, 0x7F, + 0x00, 0x41, 0x7F, 0x41, 0x00, + 0x20, 0x40, 0x41, 0x3F, 0x01, + 0x7F, 0x08, 0x14, 0x22, 0x41, + 0x7F, 0x40, 0x40, 0x40, 0x40, + 0x7F, 0x02, 0x1C, 0x02, 0x7F, + 0x7F, 0x04, 0x08, 0x10, 0x7F, + 0x3E, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x09, 0x09, 0x09, 0x06, + 0x3E, 0x41, 0x51, 0x21, 0x5E, + 0x7F, 0x09, 0x19, 0x29, 0x46, + 0x26, 0x49, 0x49, 0x49, 0x32, + 0x03, 0x01, 0x7F, 0x01, 0x03, + 0x3F, 0x40, 0x40, 0x40, 0x3F, + 0x1F, 0x20, 0x40, 0x20, 0x1F, + 0x3F, 0x40, 0x38, 0x40, 0x3F, + 0x63, 0x14, 0x08, 0x14, 0x63, + 0x03, 0x04, 0x78, 0x04, 0x03, + 0x61, 0x59, 0x49, 0x4D, 0x43, + 0x00, 0x7F, 0x41, 0x41, 0x41, + 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, + 0x04, 0x02, 0x01, 0x02, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x03, 0x07, 0x08, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, + 0x7F, 0x28, 0x44, 0x44, 0x38, + 0x38, 0x44, 0x44, 0x44, 0x28, + 0x38, 0x44, 0x44, 0x28, 0x7F, + 0x38, 0x54, 0x54, 0x54, 0x18, + 0x00, 0x08, 0x7E, 0x09, 0x02, + 0x18, 0xA4, 0xA4, 0x9C, 0x78, + 0x7F, 0x08, 0x04, 0x04, 0x78, + 0x00, 0x44, 0x7D, 0x40, 0x00, + 0x20, 0x40, 0x40, 0x3D, 0x00, + 0x7F, 0x10, 0x28, 0x44, 0x00, + 0x00, 0x41, 0x7F, 0x40, 0x00, + 0x7C, 0x04, 0x78, 0x04, 0x78, + 0x7C, 0x08, 0x04, 0x04, 0x78, + 0x38, 0x44, 0x44, 0x44, 0x38, + 0xFC, 0x18, 0x24, 0x24, 0x18, + 0x18, 0x24, 0x24, 0x18, 0xFC, + 0x7C, 0x08, 0x04, 0x04, 0x08, + 0x48, 0x54, 0x54, 0x54, 0x24, + 0x04, 0x04, 0x3F, 0x44, 0x24, + 0x3C, 0x40, 0x40, 0x20, 0x7C, + 0x1C, 0x20, 0x40, 0x20, 0x1C, + 0x3C, 0x40, 0x30, 0x40, 0x3C, + 0x44, 0x28, 0x10, 0x28, 0x44, + 0x4C, 0x90, 0x90, 0x90, 0x7C, + 0x44, 0x64, 0x54, 0x4C, 0x44, + 0x00, 0x08, 0x36, 0x41, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, + 0x3C, 0x26, 0x23, 0x26, 0x3C, + 0x1E, 0xA1, 0xA1, 0x61, 0x12, + 0x3A, 0x40, 0x40, 0x20, 0x7A, + 0x38, 0x54, 0x54, 0x55, 0x59, + 0x21, 0x55, 0x55, 0x79, 0x41, + 0x21, 0x54, 0x54, 0x78, 0x41, + 0x21, 0x55, 0x54, 0x78, 0x40, + 0x20, 0x54, 0x55, 0x79, 0x40, + 0x0C, 0x1E, 0x52, 0x72, 0x12, + 0x39, 0x55, 0x55, 0x55, 0x59, + 0x39, 0x54, 0x54, 0x54, 0x59, + 0x39, 0x55, 0x54, 0x54, 0x58, + 0x00, 0x00, 0x45, 0x7C, 0x41, + 0x00, 0x02, 0x45, 0x7D, 0x42, + 0x00, 0x01, 0x45, 0x7C, 0x40, + 0xF0, 0x29, 0x24, 0x29, 0xF0, + 0xF0, 0x28, 0x25, 0x28, 0xF0, + 0x7C, 0x54, 0x55, 0x45, 0x00, + 0x20, 0x54, 0x54, 0x7C, 0x54, + 0x7C, 0x0A, 0x09, 0x7F, 0x49, + 0x32, 0x49, 0x49, 0x49, 0x32, + 0x32, 0x48, 0x48, 0x48, 0x32, + 0x32, 0x4A, 0x48, 0x48, 0x30, + 0x3A, 0x41, 0x41, 0x21, 0x7A, + 0x3A, 0x42, 0x40, 0x20, 0x78, + 0x00, 0x9D, 0xA0, 0xA0, 0x7D, + 0x39, 0x44, 0x44, 0x44, 0x39, + 0x3D, 0x40, 0x40, 0x40, 0x3D, + 0x3C, 0x24, 0xFF, 0x24, 0x24, + 0x48, 0x7E, 0x49, 0x43, 0x66, + 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, + 0xFF, 0x09, 0x29, 0xF6, 0x20, + 0xC0, 0x88, 0x7E, 0x09, 0x03, + 0x20, 0x54, 0x54, 0x79, 0x41, + 0x00, 0x00, 0x44, 0x7D, 0x41, + 0x30, 0x48, 0x48, 0x4A, 0x32, + 0x38, 0x40, 0x40, 0x22, 0x7A, + 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, + 0x26, 0x29, 0x29, 0x2F, 0x28, + 0x26, 0x29, 0x29, 0x29, 0x26, + 0x30, 0x48, 0x4D, 0x40, 0x20, + 0x38, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, + 0x2F, 0x10, 0xC8, 0xAC, 0xBA, + 0x2F, 0x10, 0x28, 0x34, 0xFA, + 0x00, 0x00, 0x7B, 0x00, 0x00, + 0x08, 0x14, 0x2A, 0x14, 0x22, + 0x22, 0x14, 0x2A, 0x14, 0x08, + 0xAA, 0x00, 0x55, 0x00, 0xAA, + 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x10, 0x10, 0x10, 0xFF, 0x00, + 0x14, 0x14, 0x14, 0xFF, 0x00, + 0x10, 0x10, 0xFF, 0x00, 0xFF, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x14, 0x14, 0x14, 0xFC, 0x00, + 0x14, 0x14, 0xF7, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x14, 0x14, 0xF4, 0x04, 0xFC, + 0x14, 0x14, 0x17, 0x10, 0x1F, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, + 0x10, 0x10, 0x10, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0xF0, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0xFF, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x14, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, + 0x14, 0x14, 0x17, 0x10, 0x17, + 0x14, 0x14, 0xF4, 0x04, 0xF4, + 0x00, 0x00, 0xFF, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0xF7, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x17, 0x14, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0xF4, 0x14, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, + 0x00, 0x00, 0x00, 0xFC, 0x14, + 0x00, 0x00, 0xF0, 0x10, 0xF0, + 0x10, 0x10, 0xFF, 0x10, 0xFF, + 0x14, 0x14, 0x14, 0xFF, 0x14, + 0x10, 0x10, 0x10, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x38, 0x44, 0x44, 0x38, 0x44, + 0x7C, 0x2A, 0x2A, 0x3E, 0x14, + 0x7E, 0x02, 0x02, 0x06, 0x06, + 0x02, 0x7E, 0x02, 0x7E, 0x02, + 0x63, 0x55, 0x49, 0x41, 0x63, + 0x38, 0x44, 0x44, 0x3C, 0x04, + 0x40, 0x7E, 0x20, 0x1E, 0x20, + 0x06, 0x02, 0x7E, 0x02, 0x02, + 0x99, 0xA5, 0xE7, 0xA5, 0x99, + 0x1C, 0x2A, 0x49, 0x2A, 0x1C, + 0x4C, 0x72, 0x01, 0x72, 0x4C, + 0x30, 0x4A, 0x4D, 0x4D, 0x30, + 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, + 0x3E, 0x49, 0x49, 0x49, 0x00, + 0x7E, 0x01, 0x01, 0x01, 0x7E, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x44, 0x44, 0x5F, 0x44, 0x44, + 0x40, 0x51, 0x4A, 0x44, 0x40, + 0x40, 0x44, 0x4A, 0x51, 0x40, + 0x00, 0x00, 0xFF, 0x01, 0x03, + 0xE0, 0x80, 0xFF, 0x00, 0x00, + 0x08, 0x08, 0x6B, 0x6B, 0x08, + 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, + 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x00, + 0x30, 0x40, 0xFF, 0x01, 0x01, + 0x00, 0x1F, 0x01, 0x01, 0x1E, + 0x00, 0x19, 0x1D, 0x17, 0x12, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/drivers/qwiic/util/font8x16.h b/drivers/qwiic/util/font8x16.h new file mode 100644 index 000000000..c070e4ec8 --- /dev/null +++ b/drivers/qwiic/util/font8x16.h @@ -0,0 +1,127 @@ +/****************************************************************************** +font8x16.h +Definition for medium font + +This file was imported from the MicroView library, written by GeekAmmo +(https://github.com/geekammo/MicroView-Arduino-Library), and released under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 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 . + +Modified by: +Emil Varughese @ Edwin Robotics Pvt. Ltd. +July 27, 2015 +https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/ +******************************************************************************/ +#pragma once + +#include "progmem.h" + +static const unsigned char font8x16[] PROGMEM = { + // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256) + 8,16,32,96,2,56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBE, 0x90, 0xD0, 0xBE, 0x90, 0x00, + 0x00, 0x1C, 0x62, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x0C, 0x12, 0x92, 0x4C, 0xB0, 0x88, 0x06, 0x00, + 0x80, 0x7C, 0x62, 0xB2, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x18, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, + 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, + 0xF8, 0x04, 0xC2, 0x32, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, + 0xC0, 0xA0, 0x98, 0x84, 0xFE, 0x80, 0x80, 0x00, 0x00, 0x1E, 0x12, 0x12, 0x22, 0xC2, 0x00, 0x00, + 0xF8, 0x44, 0x22, 0x22, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, + 0x00, 0x8C, 0x52, 0x22, 0x52, 0x8C, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x26, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x00, 0x00, 0x04, 0x02, 0x01, 0x03, 0x04, 0x04, 0x03, 0x00, + 0x03, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x06, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x06, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x03, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, + 0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x04, 0x72, 0x8A, 0xFA, 0x84, 0x78, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x38, 0xC0, 0x00, 0x00, + 0x00, 0xFE, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, + 0xFE, 0x02, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, + 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x22, 0xE2, 0x00, 0x00, + 0xFE, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0xFE, 0x40, 0xB0, 0x08, 0x04, 0x02, 0x00, 0x00, + 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0C, 0x70, 0x80, 0x70, 0x0C, 0xFE, 0x00, + 0xFE, 0x0C, 0x30, 0xC0, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, + 0xFE, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, + 0x00, 0xFE, 0x42, 0x42, 0xA2, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x42, 0x80, 0x00, 0x00, + 0x02, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, + 0x06, 0x38, 0xC0, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x3E, 0xC0, 0xF0, 0x0E, 0xF0, 0xC0, 0x3E, 0x00, + 0x00, 0x06, 0x98, 0x60, 0x98, 0x06, 0x00, 0x00, 0x00, 0x06, 0x18, 0xE0, 0x18, 0x06, 0x00, 0x00, + 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x00, + 0x00, 0x06, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, + 0x40, 0x30, 0x0C, 0x0C, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, + 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, + 0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, + 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0C, 0x12, 0x11, 0x10, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x06, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, + 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, + 0x00, 0xE0, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, + 0x00, 0x20, 0xFC, 0x22, 0x22, 0x22, 0x02, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, + 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, + 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0xF0, 0x00, + 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xE0, 0x00, 0x00, + 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, + 0x00, 0xF0, 0x20, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x20, 0x00, 0x00, + 0x00, 0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x00, 0x70, 0x80, 0x00, 0x80, 0x70, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0x00, 0xF0, 0x00, + 0x00, 0x30, 0xC0, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00, + 0x00, 0x10, 0x10, 0x90, 0x50, 0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x7E, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x7E, 0x80, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, + 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24, 0x22, 0x1F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, + 0x00, 0x3F, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x3F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00, + 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x20, 0x20, 0x31, 0x0E, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; -- cgit v1.2.3 From df33618b26bb7ff0c0eff619b2d638490c514ce4 Mon Sep 17 00:00:00 2001 From: yiancar Date: Wed, 19 Dec 2018 13:56:44 +0000 Subject: Minor STM32 i2c driver cleanup --- drivers/arm/i2c_master.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index ab962ea95..4417dc985 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c @@ -45,8 +45,6 @@ static const I2CConfig i2cconfig = { __attribute__ ((weak)) void i2c_init(void) { - //palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); - // Try releasing special pins for a short time palSetPadMode(GPIOB, 6, PAL_MODE_INPUT); palSetPadMode(GPIOB, 7, PAL_MODE_INPUT); -- cgit v1.2.3 From b13162f7fd5a4c09dff15ff6f9713526622925a7 Mon Sep 17 00:00:00 2001 From: yiancar Date: Wed, 19 Dec 2018 13:59:58 +0000 Subject: Also fix use of weak stm32 internal pullup --- drivers/arm/i2c_master.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index 4417dc985..385bd97cb 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c @@ -51,8 +51,8 @@ void i2c_init(void) chThdSleepMilliseconds(10); - palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); - palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); + palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); + palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); //i2cInit(); //This is invoked by halInit() so no need to redo it. } -- cgit v1.2.3