Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Djinn. #17382

Merged
merged 3 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ CMakeLists.txt
.vscode/temp.sql
tags

# Ignore image files
# Ignore image/font files
*.gif
*.jpg
*.png
*.ttf
*.otf

# Things Travis sees
/.vs
Expand Down
74 changes: 74 additions & 0 deletions keyboards/tzarc/djinn/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2018-2022 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "config_common.h"

// Encoders -- right-side is reversed
#define ENCODERS_PAD_A \
{ C14 }
#define ENCODERS_PAD_B \
{ C15 }
#define ENCODERS_PAD_A_RIGHT \
{ C15 }
#define ENCODERS_PAD_B_RIGHT \
{ C14 }

#ifndef ENCODER_RESOLUTION
# define ENCODER_RESOLUTION 2
#endif // ENCODER_RESOLUTION

// Bootloader
#define STM32_BOOTLOADER_DUAL_BANK TRUE
#define STM32_BOOTLOADER_DUAL_BANK_GPIO B7

// Peripheral power control pins
#define LCD_POWER_ENABLE_PIN A6

// Split configuration
#define SPLIT_TRANSACTION_IDS_KB RPC_ID_SYNC_STATE_KB
#define SPLIT_TRANSPORT_MIRROR
#define SPLIT_LAYER_STATE_ENABLE
#define SPLIT_LED_STATE_ENABLE
#define SPLIT_MODS_ENABLE
#define SPLIT_WPM_ENABLE

// SPI Configuration
#define SPI_DRIVER SPID3
#define SPI_SCK_PIN C10
#define SPI_SCK_PAL_MODE 6
#define SPI_MOSI_PIN C12
#define SPI_MOSI_PAL_MODE 6
#define SPI_MISO_PIN C11
#define SPI_MISO_PAL_MODE 6

// LCD Configuration
#define LCD_RST_PIN B3
#define LCD_CS_PIN D2
#define LCD_DC_PIN A15
#ifndef LCD_ACTIVITY_TIMEOUT
# define LCD_ACTIVITY_TIMEOUT 30000
#endif // LCD_ACTIVITY_TIMEOUT

// Backlight driver (to control LCD backlight)
#define BACKLIGHT_LEVELS 4
#define BACKLIGHT_PWM_DRIVER PWMD17
#define BACKLIGHT_PWM_CHANNEL 1
#define BACKLIGHT_PAL_MODE 1

// RGB configuration
#define RGB_DI_PIN B2
#define WS2812_EXTERNAL_PULLUP
#define WS2812_PWM_DRIVER PWMD20
#define WS2812_PWM_CHANNEL 1
#define WS2812_PWM_PAL_MODE 3
#define WS2812_DMA_STREAM STM32_DMA1_STREAM1
#define WS2812_DMA_CHANNEL 1
#define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM20_UP

// Audio configuration
#define AUDIO_PIN A5
#define AUDIO_PIN_ALT A4
#define AUDIO_PIN_ALT_AS_NEGATIVE
#ifndef STARTUP_SONG
# define STARTUP_SONG SONG(STARTUP_SOUND)
#endif // STARTUP_SONG
199 changes: 199 additions & 0 deletions keyboards/tzarc/djinn/djinn.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// Copyright 2018-2022 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#include <string.h>
#include "quantum.h"
#include <hal_pal.h>
#include "djinn.h"
#include "serial.h"
#include "split_util.h"
#include "qp.h"

painter_device_t lcd;

// clang-format off
#ifdef SWAP_HANDS_ENABLE
const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
{ { 6, 6 }, { 5, 6 }, { 4, 6 }, { 3, 6 }, { 2, 6 }, { 1, 6 }, { 0, 6 } },
{ { 6, 7 }, { 5, 7 }, { 4, 7 }, { 3, 7 }, { 2, 7 }, { 1, 7 }, { 0, 7 } },
{ { 6, 8 }, { 5, 8 }, { 4, 8 }, { 3, 8 }, { 2, 8 }, { 1, 8 }, { 0, 8 } },
{ { 6, 9 }, { 5, 9 }, { 4, 9 }, { 3, 9 }, { 2, 9 }, { 1, 9 }, { 0, 9 } },
{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 10 }, { 5, 10 }, { 4, 10 }, { 3, 10 } },
{ { 0, 0 }, { 6, 11 }, { 5, 11 }, { 4, 11 }, { 3, 11 }, { 2, 11 }, { 1, 11 } },

{ { 6, 0 }, { 5, 0 }, { 4, 0 }, { 3, 0 }, { 2, 0 }, { 1, 0 }, { 0, 0 } },
{ { 6, 1 }, { 5, 1 }, { 4, 1 }, { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 1 } },
{ { 6, 2 }, { 5, 2 }, { 4, 2 }, { 3, 2 }, { 2, 2 }, { 1, 2 }, { 0, 2 } },
{ { 6, 3 }, { 5, 3 }, { 4, 3 }, { 3, 3 }, { 2, 3 }, { 1, 3 }, { 0, 3 } },
{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 4 }, { 5, 4 }, { 4, 4 }, { 3, 4 } },
{ { 0, 0 }, { 6, 5 }, { 5, 5 }, { 4, 5 }, { 3, 5 }, { 2, 5 }, { 1, 5 } },
};
# ifdef ENCODER_MAP_ENABLE
const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = { 1, 0 };
# endif // ENCODER_MAP_ENABLE
#endif // SWAP_HANDS_ENABLE
// clang-format on

void board_init(void) {
usbpd_init();
}

//----------------------------------------------------------
// Initialisation

void keyboard_post_init_kb(void) {
// Register keyboard state sync split transaction
transaction_register_rpc(RPC_ID_SYNC_STATE_KB, kb_state_sync_slave);

// Reset the initial shared data value between master and slave
memset(&kb_state, 0, sizeof(kb_state));

// Turn off increased current limits
setPinOutput(RGB_CURR_1500mA_OK_PIN);
writePinLow(RGB_CURR_1500mA_OK_PIN);
setPinOutput(RGB_CURR_3000mA_OK_PIN);
writePinLow(RGB_CURR_3000mA_OK_PIN);

// Turn on the RGB
setPinOutput(RGB_POWER_ENABLE_PIN);
writePinHigh(RGB_POWER_ENABLE_PIN);

#ifdef EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN
setPinOutput(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN);
writePinHigh(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN);
#endif // EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN

// Turn on the LCD
setPinOutput(LCD_POWER_ENABLE_PIN);
writePinHigh(LCD_POWER_ENABLE_PIN);

// Let the LCD get some power...
wait_ms(150);

// Initialise the LCD
lcd = qp_ili9341_make_spi_device(320, 240, LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN, 4, 3);
qp_init(lcd, QP_ROTATION_0);

// Turn on the LCD and clear the display
kb_state.lcd_power = 1;
qp_power(lcd, true);
qp_rect(lcd, 0, 0, 239, 319, HSV_BLACK, true);

// Turn on the LCD backlight
backlight_enable();
backlight_level(BACKLIGHT_LEVELS);

// Allow for user post-init
keyboard_post_init_user();
}

//----------------------------------------------------------
// RGB brightness scaling dependent on USBPD state

#if defined(RGB_MATRIX_ENABLE)
RGB rgb_matrix_hsv_to_rgb(HSV hsv) {
float scale;
switch (kb_state.current_setting) {
default:
case USBPD_500MA:
scale = 0.35f;
break;
case USBPD_1500MA:
scale = 0.75f;
break;
case USBPD_3000MA:
scale = 1.0f;
break;
}

hsv.v = (uint8_t)(hsv.v * scale);
return hsv_to_rgb(hsv);
}
#endif

//----------------------------------------------------------
// UI Placeholder, implemented in themes

__attribute__((weak)) void draw_ui_user(void) {}

//----------------------------------------------------------
// Housekeeping

void housekeeping_task_kb(void) {
// Update kb_state so we can send to slave
kb_state_update();

// Data sync from master to slave
kb_state_sync();

// Work out if we've changed our current limit, update the limiter circuit switches
static uint8_t current_setting = USBPD_500MA;
if (current_setting != kb_state.current_setting) {
current_setting = kb_state.current_setting;
switch (current_setting) {
default:
case USBPD_500MA:
writePinLow(RGB_CURR_1500mA_OK_PIN);
writePinLow(RGB_CURR_3000mA_OK_PIN);
break;
case USBPD_1500MA:
writePinHigh(RGB_CURR_1500mA_OK_PIN);
writePinLow(RGB_CURR_3000mA_OK_PIN);
break;
case USBPD_3000MA:
writePinHigh(RGB_CURR_1500mA_OK_PIN);
writePinHigh(RGB_CURR_3000mA_OK_PIN);
break;
}

// If we've changed the current limit, toggle rgb off and on if it was on, to force a brightness update on all LEDs
if (is_keyboard_master() && rgb_matrix_is_enabled()) {
rgb_matrix_disable_noeeprom();
rgb_matrix_enable_noeeprom();
}
}

// Turn on/off the LCD
static bool lcd_on = false;
if (lcd_on != (bool)kb_state.lcd_power) {
lcd_on = (bool)kb_state.lcd_power;
qp_power(lcd, lcd_on);
}

// Enable/disable RGB
if (lcd_on) {
// Turn on RGB
writePinHigh(RGB_POWER_ENABLE_PIN);
// Modify the RGB state if different to the LCD state
if (rgb_matrix_is_enabled() != lcd_on) {
// Wait for a small amount of time to allow the RGB capacitors to charge, before enabling RGB output
wait_ms(10);
// Enable RGB
rgb_matrix_enable_noeeprom();
}
} else {
// Turn off RGB
writePinLow(RGB_POWER_ENABLE_PIN);
// Disable the PWM output for the RGB
if (rgb_matrix_is_enabled() != lcd_on) {
rgb_matrix_disable_noeeprom();
}
}

// Match the backlight to the LCD state
if (is_keyboard_master() && is_backlight_enabled() != lcd_on) {
if (lcd_on)
backlight_enable();
else
backlight_disable();
}

// Draw the UI
if (kb_state.lcd_power) {
draw_ui_user();
}

// Go into low-scan interrupt-based mode if we haven't had any matrix activity in the last 250 milliseconds
if (last_input_activity_elapsed() > 250) {
matrix_wait_for_interrupt();
}
}
32 changes: 32 additions & 0 deletions keyboards/tzarc/djinn/djinn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2018-2022 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "quantum.h"
#include "qp.h"

//----------------------------------------------------------
// General stuff

extern painter_device_t lcd;

void matrix_wait_for_interrupt(void);

void usbpd_update(void);
const char* usbpd_str(usbpd_allowance_t allowance);

//----------------------------------------------------------
// Runtime data sync -- keyboard

#pragma pack(push)
#pragma pack(1)
typedef struct kb_runtime_config {
unsigned lcd_power : 1;
usbpd_allowance_t current_setting : 2;
} kb_runtime_config;
#pragma pack(pop)

extern kb_runtime_config kb_state;

void kb_state_update(void);
void kb_state_sync(void);
void kb_state_sync_slave(uint8_t m2s_size, const void* m2s_buffer, uint8_t s2m_size, void* s2m_buffer);
Loading