aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/rubi/config.h65
-rw-r--r--keyboards/rubi/info.json31
-rw-r--r--keyboards/rubi/keymaps/default/keymap.c58
-rw-r--r--keyboards/rubi/keymaps/default/readme.md4
-rw-r--r--keyboards/rubi/keymaps/via/keymap.c53
-rw-r--r--keyboards/rubi/keymaps/via/rules.mk2
-rw-r--r--keyboards/rubi/lib/calc.c261
-rw-r--r--keyboards/rubi/lib/encoder.c115
-rw-r--r--keyboards/rubi/lib/glcdfont.c246
-rw-r--r--keyboards/rubi/lib/oled.c268
-rw-r--r--keyboards/rubi/lib/oled.h32
-rw-r--r--keyboards/rubi/readme.md23
-rw-r--r--keyboards/rubi/rubi.c108
-rw-r--r--keyboards/rubi/rubi.h102
-rw-r--r--keyboards/rubi/rules.mk28
15 files changed, 1396 insertions, 0 deletions
diff --git a/keyboards/rubi/config.h b/keyboards/rubi/config.h
new file mode 100644
index 000000000..5b6b1c453
--- /dev/null
+++ b/keyboards/rubi/config.h
@@ -0,0 +1,65 @@
1/*
2Copyright 2021 gregorio
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include "config_common.h"
21
22/* USB Device descriptor parameter */
23#define VENDOR_ID 0x4752
24#define PRODUCT_ID 0x5242
25#define DEVICE_VER 0x0001
26#define MANUFACTURER gregorio
27#define PRODUCT Rubi
28
29/* key matrix size */
30#define MATRIX_ROWS 5
31#define MATRIX_COLS 4
32
33/*
34 * Keyboard Matrix Assignments
35 *
36 * Change this to how you wired your keyboard
37 * COLS: AVR pins used for columns, left to right
38 * ROWS: AVR pins used for rows, top to bottom
39 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
40 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
41 *
42 */
43#define MATRIX_ROW_PINS { F0, F1, F4, F5, F6 }
44#define MATRIX_COL_PINS { B3, B2, B1, F7 }
45#define UNUSED_PINS
46
47#define ENCODERS_PAD_A { D7 }
48#define ENCODERS_PAD_B { D6 }
49
50/* COL2ROW, ROW2COL */
51#define DIODE_DIRECTION COL2ROW
52
53/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
54#define DEBOUNCE 5
55
56/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
57#define LOCKING_SUPPORT_ENABLE
58/* Locking resynchronize hack */
59#define LOCKING_RESYNC_ENABLE
60
61/* disable these deprecated features by default */
62#define NO_ACTION_MACRO
63#define NO_ACTION_FUNCTION
64
65#define OLED_FONT_H "lib/glcdfont.c"
diff --git a/keyboards/rubi/info.json b/keyboards/rubi/info.json
new file mode 100644
index 000000000..72b6242fc
--- /dev/null
+++ b/keyboards/rubi/info.json
@@ -0,0 +1,31 @@
1{
2 "keyboard_name": "Rubi",
3 "url": "https://github.com/ohchiko/qmk_firmware/tree/master/keyboards/rubi",
4 "maintainer": "gregorio",
5 "width": 4,
6 "height": 5,
7 "layouts": {
8 "LAYOUT": {
9 "layout": [
10 {"x":3, "y":0},
11 {"x":0, "y":1.25},
12 {"x":1, "y":1.25},
13 {"x":2, "y":1.25},
14 {"x":3, "y":1.25},
15 {"x":0, "y":2.25},
16 {"x":1, "y":2.25},
17 {"x":2, "y":2.25},
18 {"x":3, "y":2.25, "h":2},
19 {"x":0, "y":3.25},
20 {"x":1, "y":3.25},
21 {"x":2, "y":3.25},
22 {"x":0, "y":4.25},
23 {"x":1, "y":4.25},
24 {"x":2, "y":4.25},
25 {"x":3, "y":4.25, "h":2},
26 {"x":0, "y":5.25, "w":2},
27 {"x":2, "y":5.25}
28 ]
29 }
30 }
31} \ No newline at end of file
diff --git a/keyboards/rubi/keymaps/default/keymap.c b/keyboards/rubi/keymaps/default/keymap.c
new file mode 100644
index 000000000..054e3ce23
--- /dev/null
+++ b/keyboards/rubi/keymaps/default/keymap.c
@@ -0,0 +1,58 @@
1/* Copyright 2020 gregorio
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include QMK_KEYBOARD_H
17
18
19// enum custom_keycodes {
20// FIRST = NEW_SAFE_RANGE,
21// };
22
23// Defines names for use in layer keycodes and the keymap
24const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
25 /* Base */
26 [0] = LAYOUT(
27 ENC_PRESS,
28 KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
29 KC_P7 , KC_P8 , KC_P9 , KC_PPLS,
30 KC_P4 , KC_P5 , KC_P6 ,
31 KC_P1 , KC_P2 , KC_P3 , KC_PENT,
32 KC_P0 , LT(2, KC_PDOT)
33 ),
34 [1] = LAYOUT(
35 KC_TRNS,
36 KC_C , KC_SLSH, CL_STAR, KC_MINS,
37 KC_7 , KC_8 , KC_9 , CL_PLUS,
38 KC_4 , KC_5 , KC_6 ,
39 KC_1 , KC_2 , KC_3 , KC_EQL,
40 KC_0 , KC_DOT
41 ),
42 [2] = LAYOUT(
43 KC_TRNS,
44 KC_TRNS, KC_N , KC_S , KC_R ,
45 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
46 KC_TRNS, KC_TRNS, KC_TRNS,
47 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
48 KC_TRNS, KC_TRNS
49 ),
50 [3] = LAYOUT(
51 KC_TRNS,
52 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
53 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
54 KC_TRNS, RESET , KC_TRNS,
55 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
56 KC_TRNS, KC_TRNS
57 ),
58};
diff --git a/keyboards/rubi/keymaps/default/readme.md b/keyboards/rubi/keymaps/default/readme.md
new file mode 100644
index 000000000..1e7cbc85f
--- /dev/null
+++ b/keyboards/rubi/keymaps/default/readme.md
@@ -0,0 +1,4 @@
1# The default keymap for Rubi
2
3[KLE](http://www.keyboard-layout-editor.com/#/gists/984e9039971cf4738d507150b4494190)
4![Rubi Default Keymap](https://i.imgur.com/bsG8BdW.jpg)
diff --git a/keyboards/rubi/keymaps/via/keymap.c b/keyboards/rubi/keymaps/via/keymap.c
new file mode 100644
index 000000000..3003db888
--- /dev/null
+++ b/keyboards/rubi/keymaps/via/keymap.c
@@ -0,0 +1,53 @@
1/* Copyright 2020 gregorio
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include QMK_KEYBOARD_H
17
18// Defines names for use in layer keycodes and the keymap
19const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
20 /* Base */
21 [0] = LAYOUT(
22 ENC_PRESS,
23 KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
24 KC_P7 , KC_P8 , KC_P9 , KC_PPLS,
25 KC_P4 , KC_P5 , KC_P6 ,
26 KC_P1 , KC_P2 , KC_P3 , KC_PENT,
27 KC_P0 , LT(2, KC_PDOT)
28 ),
29 [1] = LAYOUT(
30 KC_TRNS,
31 KC_C , KC_SLSH, CL_STAR, KC_MINS,
32 KC_7 , KC_8 , KC_9 , CL_PLUS,
33 KC_4 , KC_5 , KC_6 ,
34 KC_1 , KC_2 , KC_3 , KC_EQL,
35 KC_0 , KC_DOT
36 ),
37 [2] = LAYOUT(
38 KC_TRNS,
39 KC_TRNS, KC_N , KC_S , KC_R ,
40 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
41 KC_TRNS, KC_TRNS, KC_TRNS,
42 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
43 KC_TRNS, KC_TRNS
44 ),
45 [3] = LAYOUT(
46 KC_TRNS,
47 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
48 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
49 KC_TRNS, RESET , KC_TRNS,
50 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
51 KC_TRNS, KC_TRNS
52 ),
53};
diff --git a/keyboards/rubi/keymaps/via/rules.mk b/keyboards/rubi/keymaps/via/rules.mk
new file mode 100644
index 000000000..43061db1d
--- /dev/null
+++ b/keyboards/rubi/keymaps/via/rules.mk
@@ -0,0 +1,2 @@
1VIA_ENABLE = yes
2LTO_ENABLE = yes \ No newline at end of file
diff --git a/keyboards/rubi/lib/calc.c b/keyboards/rubi/lib/calc.c
new file mode 100644
index 000000000..7796a9be4
--- /dev/null
+++ b/keyboards/rubi/lib/calc.c
@@ -0,0 +1,261 @@
1/*
2This is the modified version of [calculator by MWWorks](https://github.com/MWWorks/mw_calc_numpad/blob/master/calc.c). Below is the quote from [MWWorks](https://github.com/MWWorks).
3
4 Calculator for QMK-based keyboard by MWWorks, https://mwworks.uk
5 This is free, usual disclaimers, don't use it to calculate megaton yields, surgery plans, etc
6
7 I did not plan to reinvent the wheel for this - I figured surely somebody somewhere has working calculator code?
8 Found lots but none that actually work like you expect a calculator to, hence DIYing it
9
10 As such, this is probably a bit janky, especially as I am a bit of a hack at C
11 Seems to be working well, with occasional glitchs, solved by clearing it
12 And some occasional floating-point issues - eg get a long decimal rather than the whole number you were expecting
13 Feel free to fix it! I think it needs to detect the precision of the two operands and then figure out what the precision of the result should be
14
15*/
16#include "rubi.h"
17
18static uint8_t calc_current_operand = 0;
19static char calc_operand_0[CALC_DIGITS+1] = "";
20static char calc_operand_1[CALC_DIGITS+1] = "";
21char calc_result[CALC_DIGITS+1] = "";
22static char calc_status[CALC_DIGITS+1] = "";
23static char calc_operator = ' ';
24static bool calc_reset = false;
25
26
27void calcBegin(void){
28}
29
30//update display
31void calcUpdate(void){
32 if (calc_display_lines == 2) {
33 if((calc_current_operand == 1) || (calc_reset)){
34 strcpy(calc_status, calc_operand_0);
35 if((strlen(calc_operand_0)>0) || (strlen(calc_operand_1)>0)){
36 uint8_t len = strlen(calc_status);
37 if (!(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')) {
38 calc_status[len] = calc_operator;
39 }
40 calc_status[len+1] = 0;
41 if(calc_reset
42 && !(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')){
43 strncat(calc_status, calc_operand_1, CALC_DIGITS-strlen(calc_status));
44 calc_operator = ' ';
45 }
46 }
47 strcpy(calc_status_display, calc_status);
48 }
49 } else if (calc_display_lines == 1) {
50 if(calc_reset
51 && !(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')){
52 calc_operator = ' ';
53 }
54 }
55 calc_operator_display = calc_operator;
56 strcpy(calc_result_display, calc_result);
57}
58
59//perform calculation on the 2 operands
60void calcOperands(void){
61 float result = 0;
62 switch (calc_operator){
63
64 //standard operators
65 case '+':
66 result = strtod(calc_operand_0, NULL) + strtod(calc_operand_1, NULL);
67 break;
68
69 case '-':
70 result = strtod(calc_operand_0, NULL) - strtod(calc_operand_1, NULL);
71 break;
72
73 case '/':
74 result = strtod(calc_operand_0, NULL) / strtod(calc_operand_1, NULL);
75 break;
76
77 case '*':
78 result = strtod(calc_operand_0, NULL) * strtod(calc_operand_1, NULL);
79 break;
80
81 //single operand operators - these are all in 2
82 case 's':
83 result = sqrt(strtod(calc_operand_0, NULL));
84 break;
85
86 case 'r':
87 result = 1/(strtod(calc_operand_0, NULL));
88 break;
89
90 }
91
92 //now convert the float result into a string
93 //we know the total string size but we need to find the size of the integer component to know how much we have for decimals
94 uint8_t magnitude = ceil(log10(result));
95 uint8_t max_decimals = CALC_DIGITS-magnitude-1;
96 //but max it at 7 because that seems the useful limit of our floats
97 if(max_decimals>7){
98 max_decimals = 7;
99 }
100 dtostrf(result, CALC_DIGITS, max_decimals, calc_result);
101
102 //now to clean up the result - we need it clean as it may be the input of next calculation
103 //this seems a lot of code to format this string :| note that this c doesn't support float in sprintf
104 uint8_t i;
105
106 //first find if theres a dot
107 uint8_t dotpos = CALC_DIGITS+1;
108 for(i=0; i<strlen(calc_result); i++){
109 if(calc_result[i] == '.'){
110 dotpos = i;
111 break;
112 }
113 }
114
115 //if there is, work back to it and remove trailing 0 or .
116 if(dotpos>=0){
117 for(i=strlen(calc_result)-1; i>=dotpos; i--){
118 if((calc_result[i] == '0') || (calc_result[i] == '.')){
119 calc_result[i] = 0;
120 }else{
121 break;
122 }
123 }
124 }
125
126 //now find how many leading spaces
127 uint8_t spaces = 0;
128 for(i=0; i<strlen(calc_result); i++){
129 if(calc_result[i] == ' '){
130 spaces++;
131 }else{
132 break;
133 }
134 }
135
136 //and shift the string
137 for(i=0; i<strlen(calc_result)-spaces; i++){
138 calc_result[i] = calc_result[i+spaces];
139 }
140 calc_result[strlen(calc_result)-spaces] = 0;
141
142 calcUpdate();
143 //the result is available as the first operand for another calculation
144 strcpy(calc_operand_0, calc_result);
145 calc_operand_1[0] = 0;
146
147}
148
149void calcInput(char input){
150 char *operand = calc_operand_0;
151 if(calc_current_operand == 1){
152 operand = calc_operand_1;
153 }
154 uint8_t len = strlen(operand);
155
156 if(
157 ((input >= 48) && (input <= 57)) ||
158 (input == '.')
159 ){
160 //if this is following an equals, then we start from scratch as if new calculation
161 if(calc_reset == true){
162 calc_reset = false;
163 calc_current_operand = 0;
164 calc_operand_0[0] = 0;
165 calc_operand_1[0] = 0;
166 operand = calc_operand_0;
167 len = 0;
168 }
169
170 if(len<CALC_DIGITS){
171 operand[len] = input;
172 operand[len+1] = 0;
173 strcpy(calc_result, operand);
174 calcUpdate();
175 }
176
177 //special input to backspace
178 }else if(input == 'x'){
179 operand[len-1] = 0;
180 strcpy(calc_result, operand);
181 calcUpdate();
182
183 //clear
184 }else if(input == 'c'){
185 operand[0] = 0;
186 calc_operand_0[0] = 0;
187 calc_operand_1[0] = 0;
188 calc_operator = ' ';
189 calc_reset = true;
190 strcpy(calc_result, operand);
191 calcUpdate();
192
193 //special input switch neg/pos
194 }else if((input == 'n') && (len>0)){
195 uint8_t i;
196
197 if(operand[0] == '-'){
198 for(i=1; i<=len; i++){
199 operand[i-1] = operand[i];
200 }
201 }else if(len<CALC_DIGITS){
202 for(i=0; i<=len; i++){
203 operand[len-i+1] = operand[len-i];
204 }
205 operand[0] = '-';
206 }
207 calc_operator = input;
208 strcpy(calc_result, operand);
209 calcUpdate();
210
211
212 //standard 2 operand operators
213 }else if((input == '+') || (input == '-') || (input == '*') || (input == '/')){
214
215 //get ready for second operand
216 if(calc_current_operand == 0){
217 calc_operator = input;
218 calc_current_operand = 1;
219 calcUpdate();
220
221 //we pressed = we now expect a new second operand
222 }else if(calc_reset){
223 calc_operator = input;
224 calc_reset = false;
225 calc_operand_1[0] = 0;
226 calcUpdate();
227
228 }else {
229 //if we use this on the second operand, calculate first, then ready for a second operand again
230 if (strlen(calc_operand_1)>0){
231 calcOperands();
232 }
233 calc_operand_1[0] = 0;
234 calc_operator = input;
235 calcUpdate();
236 }
237
238
239 }else if(input == '='){
240 //only accept = if we are on the second operand
241 if(calc_current_operand == 1){
242 //keep the second operand for a subsequent press of =; but flag to reset if start entry of new operand
243 calc_reset = true;
244 calcOperands();
245 }
246
247 //single operands - square root and reciprocal - needs to operate on 0 so it works after a previous = result
248 }else if((input == 's') || (input == 'r')){
249 //but maybe we started entering 1
250 if(calc_current_operand == 1 && !calc_reset){
251 strcpy(calc_operand_0, calc_operand_1);
252 }
253 calc_current_operand = 1;
254 calc_operand_1[0] = 0;
255 calc_operator = input;
256 calc_reset = true; //simulate another =
257 calcOperands();
258
259 }
260
261}
diff --git a/keyboards/rubi/lib/encoder.c b/keyboards/rubi/lib/encoder.c
new file mode 100644
index 000000000..06c25ad31
--- /dev/null
+++ b/keyboards/rubi/lib/encoder.c
@@ -0,0 +1,115 @@
1/*
2Copyright 2021 gregorio
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "rubi.h"
19
20void change_encoder_mode(bool reverse) {
21 if (reverse) {
22 if (encoder_mode == 0) {
23 encoder_mode = _NUM_ENCODER_MODES - 1;
24 } else {
25 encoder_mode = encoder_mode - 1;
26 }
27 } else {
28 encoder_mode = (encoder_mode + 1) % _NUM_ENCODER_MODES;
29 }
30}
31
32uint16_t handle_encoder_cw(void) {
33 uint16_t mapped_code = 0;
34
35 if (oled_mode == OLED_MODE_CALC) {
36 layer_on(2);
37 return mapped_code;
38 }
39
40 switch (encoder_mode) {
41 default:
42 case ENC_MODE_VOLUME:
43 mapped_code = KC_VOLU;
44 break;
45 case ENC_MODE_MEDIA:
46 mapped_code = KC_MEDIA_NEXT_TRACK;
47 break;
48 case ENC_MODE_BRIGHTNESS:
49 mapped_code = KC_BRIGHTNESS_UP;
50 break;
51 }
52
53 return mapped_code;
54}
55
56uint16_t handle_encoder_ccw(void) {
57 uint16_t mapped_code = 0;
58
59 if (oled_mode == OLED_MODE_CALC) {
60 layer_off(2);
61 return mapped_code;
62 }
63
64 switch (encoder_mode) {
65 default:
66 case ENC_MODE_VOLUME:
67 mapped_code = KC_VOLD;
68 break;
69 case ENC_MODE_MEDIA:
70 mapped_code = KC_MEDIA_PREV_TRACK;
71 break;
72 case ENC_MODE_BRIGHTNESS:
73 mapped_code = KC_BRIGHTNESS_DOWN;
74 break;
75 }
76
77 return mapped_code;
78}
79
80uint16_t handle_encoder_press(void) {
81 uint16_t mapped_code = 0;
82 if (get_highest_layer(layer_state) == 1) {
83 if (oled_mode == OLED_MODE_CALC) {
84 layer_on(3);
85 }
86 layer_off(1);
87 return mapped_code;
88 } else if (get_highest_layer(layer_state) == 2) {
89 if (oled_mode == OLED_MODE_CALC) {
90 layer_off(1);
91 layer_on(3);
92 } else {
93 layer_on(1);
94 }
95 layer_off(2);
96 return mapped_code;
97 } else if (get_highest_layer(layer_state) == 3) {
98 if (oled_mode == OLED_MODE_OFF) {
99 layer_off(3);
100 }
101 return mapped_code;
102 }
103
104 switch (encoder_mode) {
105 default:
106 case ENC_MODE_VOLUME:
107 mapped_code = KC_MUTE;
108 break;
109 case ENC_MODE_MEDIA:
110 mapped_code = KC_MEDIA_PLAY_PAUSE;
111 break;
112 }
113
114 return mapped_code;
115}
diff --git a/keyboards/rubi/lib/glcdfont.c b/keyboards/rubi/lib/glcdfont.c
new file mode 100644
index 000000000..1a83ed3ed
--- /dev/null
+++ b/keyboards/rubi/lib/glcdfont.c
@@ -0,0 +1,246 @@
1/* Copyright 2021 gregorio
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include "progmem.h"
19
20
21const unsigned char font[] PROGMEM = {
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
24 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
25 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
26 0x18, 0x3C, 0x7E, 0xBC, 0x18, 0x00,
27 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
28 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
29 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
30 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
31 0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
32 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
33 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
34 0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
35 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
36 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
37 0x5A, 0x3C, 0x66, 0x3C, 0x5A, 0x00,
38 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
39 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
40 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
41 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
42 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
43 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
44 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
45 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
46 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
47 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
48 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
49 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
50 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
51 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
52 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
53 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00,
56 0x00, 0x06, 0x00, 0x06, 0x00, 0x00,
57 0x14, 0x3E, 0x14, 0x3E, 0x14, 0x00,
58 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
59 0x26, 0x16, 0x08, 0x34, 0x32, 0x00,
60 0x36, 0x4A, 0x56, 0x20, 0x50, 0x00,
61 0x00, 0x0A, 0x06, 0x00, 0x00, 0x00,
62 0x00, 0x3C, 0x42, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x42, 0x3C, 0x00, 0x00,
64 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00,
65 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
66 0x00, 0xA0, 0x60, 0x00, 0x00, 0x00,
67 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
68 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
69 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
70 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
71 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
72 0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
73 0x21, 0x41, 0x45, 0x45, 0x3B, 0x00,
74 0x38, 0x26, 0x21, 0x7F, 0x20, 0x00,
75 0x2F, 0x49, 0x49, 0x49, 0x31, 0x00,
76 0x3E, 0x49, 0x49, 0x49, 0x31, 0x00,
77 0x01, 0x01, 0x61, 0x19, 0x07, 0x00,
78 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
79 0x4E, 0x51, 0x51, 0x51, 0x3E, 0x00,
80 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
81 0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
82 0x00, 0x08, 0x14, 0x22, 0x00, 0x00,
83 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
84 0x00, 0x00, 0x22, 0x14, 0x08, 0x00,
85 0x00, 0x04, 0x52, 0x0A, 0x04, 0x00,
86 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
87 0x7E, 0x09, 0x09, 0x09, 0x7E, 0x00,
88 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
89 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
90 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
91 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
92 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
93 0x3E, 0x41, 0x49, 0x49, 0x3A, 0x00,
94 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
95 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
96 0x20, 0x41, 0x41, 0x3F, 0x00, 0x00,
97 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
98 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
99 0x7F, 0x02, 0x04, 0x02, 0x7F, 0x00,
100 0x7F, 0x02, 0x04, 0x08, 0x7F, 0x00,
101 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
102 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
103 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
104 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
105 0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
106 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00,
107 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
108 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
109 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
110 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
111 0x07, 0x08, 0x70, 0x08, 0x07, 0x00,
112 0x61, 0x51, 0x49, 0x45, 0x43, 0x00,
113 0x00, 0x7F, 0x41, 0x41, 0x00, 0x00,
114 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
115 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,
116 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
117 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
118 0x00, 0x00, 0x06, 0x0A, 0x00, 0x00,
119 0x20, 0x54, 0x54, 0x54, 0x78, 0x00,
120 0x7E, 0x48, 0x48, 0x48, 0x30, 0x00,
121 0x30, 0x48, 0x48, 0x48, 0x48, 0x00,
122 0x30, 0x48, 0x48, 0x48, 0x7E, 0x00,
123 0x38, 0x54, 0x54, 0x54, 0x58, 0x00,
124 0x00, 0x08, 0x7C, 0x0A, 0x00, 0x00,
125 0x98, 0xA4, 0xA4, 0xA4, 0x78, 0x00,
126 0x7E, 0x08, 0x08, 0x08, 0x70, 0x00,
127 0x00, 0x00, 0x7A, 0x00, 0x00, 0x00,
128 0x20, 0x40, 0x40, 0x3A, 0x00, 0x00,
129 0x7E, 0x10, 0x28, 0x44, 0x00, 0x00,
130 0x00, 0x00, 0x7E, 0x40, 0x00, 0x00,
131 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
132 0x7C, 0x04, 0x04, 0x04, 0x78, 0x00,
133 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
134 0xFC, 0x24, 0x24, 0x24, 0x18, 0x00,
135 0x18, 0x24, 0x24, 0x24, 0xFC, 0x00,
136 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
137 0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
138 0x00, 0x04, 0x7E, 0x44, 0x00, 0x00,
139 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
140 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
141 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
142 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
143 0x5C, 0xA0, 0xA0, 0xA0, 0x7C, 0x00,
144 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
145 0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
146 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
147 0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
148 0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
149 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
150 0x7E, 0xFF, 0x81, 0xFB, 0xF7, 0xEF,
151 0x81, 0xFF, 0xC1, 0xBF, 0xBF, 0xBF,
152 0xC1, 0xFF, 0x81, 0xFB, 0xF7, 0xFB,
153 0x81, 0xFF, 0x7E, 0x00, 0x00, 0x00,
154 0x7E, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
155 0xDB, 0xFF, 0x83, 0xED, 0xED, 0xED,
156 0x83, 0xFF, 0x81, 0xED, 0xED, 0xED,
157 0xF3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
158 0x7E, 0xFF, 0xE1, 0xDF, 0xBF, 0xDF,
159 0xE1, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
160 0xC3, 0xFF, 0x81, 0xBF, 0xBF, 0xBF,
161 0xBF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
162 0x7E, 0xFF, 0x81, 0xB5, 0xB5, 0xB5,
163 0xCB, 0xFF, 0x81, 0xED, 0xCD, 0xAD,
164 0xB3, 0xFF, 0xFD, 0xFD, 0x81, 0xFD,
165 0xFD, 0xFF, 0x7E, 0x00, 0x00, 0x00,
166 0x7E, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
167 0xDB, 0xFF, 0x83, 0xED, 0xED, 0xED,
168 0x83, 0xFF, 0x81, 0xBF, 0xBF, 0xBF,
169 0xBF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x08, 0x08, 0x3E,
171 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
173 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x3E, 0x6F, 0x5F, 0x63,
175 0x7B, 0x7B, 0x3E, 0x00, 0x00, 0x00,
176 0x00, 0x00, 0x3E, 0x7F, 0x59, 0x6F,
177 0x77, 0x7B, 0x3E, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x14, 0x08, 0x3E,
179 0x08, 0x14, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x08, 0x08, 0x2A,
181 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x7E, 0x04, 0x08, 0x10,
183 0x7E, 0x00, 0x3E, 0x40, 0x40, 0x40,
184 0x3E, 0x00, 0x7E, 0x04, 0x08, 0x04,
185 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42,
187 0x24, 0x00, 0x7C, 0x12, 0x12, 0x12,
188 0x7C, 0x00, 0x7E, 0x12, 0x12, 0x12,
189 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x7E, 0xFF, 0x81, 0xFB, 0xE7, 0xFB,
191 0x81, 0xFF, 0x81, 0xB5, 0xB5, 0xB5,
192 0xBD, 0xFF, 0x81, 0xBD, 0xBD, 0xBD,
193 0xC3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
194 0x7E, 0xFF, 0x81, 0xB5, 0xB5, 0xB5,
195 0xCB, 0xFF, 0x81, 0xEF, 0xF7, 0xEB,
196 0x9D, 0xFF, 0x81, 0xBF, 0xBF, 0xBF,
197 0xBF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
198 0x7E, 0xFF, 0x81, 0xED, 0xED, 0xED,
199 0xF3, 0xFF, 0x83, 0xED, 0xED, 0xED,
200 0x83, 0xFF, 0x81, 0xBD, 0xBD, 0xBD,
201 0xC3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x3E, 0x77, 0x6F, 0x77,
203 0x7B, 0x77, 0x3E, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x08, 0x10, 0x08,
205 0x04, 0x08, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x3E, 0x77, 0x77, 0x55,
207 0x77, 0x77, 0x3E, 0x00, 0x00, 0x00,
208 0x7E, 0xFF, 0xB3, 0xAD, 0xAD, 0xAD,
209 0xDB, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
210 0xDB, 0xFF, 0x81, 0xED, 0xCD, 0xAD,
211 0xB3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x10, 0x20, 0x1C,
213 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42,
215 0x24, 0x00, 0x7C, 0x12, 0x12, 0x12,
216 0x7C, 0x00, 0x7E, 0x40, 0x40, 0x40,
217 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x7E, 0x12, 0x12, 0x12,
219 0x0C, 0x00, 0x7C, 0x12, 0x12, 0x12,
220 0x7C, 0x00, 0x7E, 0x42, 0x42, 0x42,
221 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
222 0x7E, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD,
223 0xC3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
224 0x7E, 0xFF, 0xFF, 0xBB, 0x81, 0xBF,
225 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
226 0x7E, 0xFF, 0x9B, 0xAD, 0xAD, 0xAD,
227 0xB3, 0xFF, 0x7E, 0x00, 0x00, 0x00,
228 0x7E, 0xFF, 0xDD, 0xBD, 0xB5, 0xB5,
229 0xC9, 0xFF, 0x7E, 0x00, 0x00, 0x00,
230 0x7E, 0xFF, 0xE7, 0xEB, 0xED, 0x81,
231 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00,
232 0x7E, 0xFF, 0xD1, 0xB5, 0xB5, 0xB5,
233 0xCD, 0xFF, 0x7E, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x3E, 0x77, 0x77, 0x41,
235 0x77, 0x77, 0x3E, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x3E, 0x77, 0x77, 0x77,
237 0x77, 0x77, 0x3E, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x3E, 0x6B, 0x77, 0x41,
239 0x77, 0x6B, 0x3E, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x4C, 0x52, 0x52, 0x52,
241 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42,
242 0x24, 0x00, 0x7E, 0x12, 0x32, 0x52,
243 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x26, 0x10,
245 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
246};
diff --git a/keyboards/rubi/lib/oled.c b/keyboards/rubi/lib/oled.c
new file mode 100644
index 000000000..d48d27323
--- /dev/null
+++ b/keyboards/rubi/lib/oled.c
@@ -0,0 +1,268 @@
1/*
2Copyright 2021 gregorio
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include QMK_KEYBOARD_H
19#include "./lib/oled.h"
20
21bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) {
22 return process_record_user(keycode, record);
23}
24
25void change_oled_mode(void) {
26 oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
27}
28
29void render_layer_section(void) {
30 // Layer indicators
31 static const char PROGMEM layer_0[] = {0xc8, 0xc9, 0};
32 static const char PROGMEM layer_1[] = {0xca, 0xcb, 0};
33 static const char PROGMEM layer_2[] = {0xcc, 0xcd, 0};
34 static const char PROGMEM layer_3[] = {0xce, 0xcf, 0};
35
36 oled_set_cursor(oled_max_chars()-15, 0);
37 oled_write_P(PSTR("LAYER"), false);
38 switch (get_highest_layer(layer_state)) {
39 case 0:
40 oled_write_P(layer_0, false);
41 break;
42 case 1:
43 oled_write_P(layer_1, false);
44 break;
45 case 2:
46 oled_write_P(layer_2, false);
47 break;
48 case 3:
49 oled_write_P(layer_3, false);
50 break;
51 default:
52 oled_write_P(PSTR("? "), false);
53 break;
54 }
55}
56
57void render_encoder_section(void) {
58 static const char PROGMEM enc_vol[] = {0x88, 0x89, 0x8a, 0x8b, 0};
59 static const char PROGMEM enc_med[] = {0xa8, 0xa9, 0xaa, 0xab, 0};
60 static const char PROGMEM enc_brt[] = {0x8c, 0x8d, 0x8e, 0x8f, 0};
61
62 oled_set_cursor(oled_max_chars()-7, 0);
63 oled_write_P(PSTR("ENC"), false);
64 switch (encoder_mode) {
65 default:
66 case ENC_MODE_VOLUME:
67 oled_write_P(enc_vol, false);
68 break;
69 case ENC_MODE_MEDIA:
70 oled_write_P(enc_med, false);
71 break;
72 case ENC_MODE_BRIGHTNESS:
73 oled_write_P(enc_brt, false);
74 break;
75 }
76}
77
78void render_numlock_section(void) {
79 static const char PROGMEM num_on[] = {0x80, 0x81, 0x82, 0x83, 0};
80 static const char PROGMEM num_off[] = {0xa0, 0xa1, 0xa2, 0xa3, 0};
81 static const char PROGMEM cap_on[] = {0x84, 0x85, 0x86, 0x87, 0};
82 static const char PROGMEM cap_off[] = {0xa4, 0xa5, 0xa6, 0xa7, 0};
83 static const char PROGMEM scr_on[] = {0xba, 0xbb, 0xbc, 0xbd, 0};
84 static const char PROGMEM scr_off[] = {0xda, 0xdb, 0xdc, 0xdd, 0};
85
86 led_t led_state = host_keyboard_led_state();
87
88 oled_set_cursor(oled_max_chars()-12, 3);
89 // num lock
90 oled_write_P(led_state.num_lock ? num_on : num_off, false);
91 oled_write_P(led_state.caps_lock ? cap_on : cap_off, false);
92 oled_write_P(led_state.scroll_lock ? scr_on : scr_off, false);
93}
94
95void render_mode_section(void) {
96 static const char PROGMEM pad_on[] = {0xb0, 0xb1, 0xb2, 0xb3, 0};
97 static const char PROGMEM pad_off[] = {0xc4, 0xc5, 0xc6, 0xc7, 0};
98 static const char PROGMEM cal_on[] = {0x90, 0x91, 0x92, 0x93, 0};
99 static const char PROGMEM cal_off[] = {0xc0, 0xc1, 0xc2, 0xc3, 0};
100
101 if (oled_mode == OLED_MODE_CALC) {
102 oled_set_cursor(0, 0);
103 oled_write_P(pad_off, false);
104 oled_set_cursor(0, 1);
105 oled_write_P(cal_on, false);
106 } else {
107 oled_set_cursor(0, 0);
108 oled_write_P(pad_on, false);
109 oled_set_cursor(0, 1);
110 oled_write_P(cal_off, false);
111 }
112}
113
114void render_calc_section(void) {
115 static const char PROGMEM add_on[] = {0xd4, 0xd5, 0};
116 static const char PROGMEM add_off[] = {0x94, 0x95, 0};
117 static const char PROGMEM sub_on[] = {0xd6, 0xd7, 0};
118 static const char PROGMEM sub_off[] = {0x96, 0x97, 0};
119 static const char PROGMEM mul_on[] = {0xd8, 0xd9, 0};
120 static const char PROGMEM mul_off[] = {0x9c, 0x9d, 0};
121 static const char PROGMEM div_on[] = {0xb8, 0xb9, 0};
122 static const char PROGMEM div_off[] = {0x9e, 0x9f, 0};
123 static const char PROGMEM sqr_on[] = {0x98, 0x99, 0};
124 static const char PROGMEM sqr_off[] = {0xbe, 0xbf, 0};
125 static const char PROGMEM rec_on[] = {0x9a, 0x9b, 0};
126 static const char PROGMEM rec_off[] = {0xde, 0xdf, 0};
127 static const char PROGMEM neg_on[] = {0xb4, 0xb5, 0};
128 static const char PROGMEM neg_off[] = {0xb6, 0xb7, 0};
129
130
131 if (oled_mode == OLED_MODE_CALC) {
132 if (get_highest_layer(layer_state) == 1) {
133 oled_set_cursor(oled_max_chars()-8, 0);
134
135 switch (calc_operator_display) {
136 case '+':
137 oled_write_P(div_off, false);
138 oled_write_P(mul_off, false);
139 oled_write_P(sub_off, false);
140 oled_write_P(add_on, false);
141 break;
142 case '-':
143 oled_write_P(div_off, false);
144 oled_write_P(mul_off, false);
145 oled_write_P(sub_on, false);
146 oled_write_P(add_off, false);
147 break;
148 case '*':
149 oled_write_P(div_off, false);
150 oled_write_P(mul_on, false);
151 oled_write_P(sub_off, false);
152 oled_write_P(add_off, false);
153 break;
154 case '/':
155 oled_write_P(div_on, false);
156 oled_write_P(mul_off, false);
157 oled_write_P(sub_off, false);
158 oled_write_P(add_off, false);
159 break;
160 case 's':
161 case 'r':
162 case 'n':
163 layer_on(2);
164 break;
165 default:
166 oled_write_P(div_off, false);
167 oled_write_P(mul_off, false);
168 oled_write_P(sub_off, false);
169 oled_write_P(add_off, false);
170 break;
171 }
172 } else if (get_highest_layer(layer_state) == 2) {
173 oled_set_cursor(oled_max_chars()-6, 0);
174
175 switch (calc_operator_display) {
176 case '+':
177 case '-':
178 case '*':
179 case '/':
180 layer_off(2);
181 break;
182 case 's':
183 oled_write_P(neg_off, false);
184 oled_write_P(sqr_on, false);
185 oled_write_P(rec_off, false);
186 break;
187 case 'r':
188 oled_write_P(neg_off, false);
189 oled_write_P(sqr_off, false);
190 oled_write_P(rec_on, false);
191 break;
192 case 'n':
193 oled_write_P(neg_on, false);
194 oled_write_P(sqr_off, false);
195 oled_write_P(rec_off, false);
196 break;
197 default:
198 oled_write_P(neg_off, false);
199 oled_write_P(sqr_off, false);
200 oled_write_P(rec_off, false);
201 break;
202 }
203 }
204
205 if (calc_display_lines == 1) {
206 oled_set_cursor(oled_max_chars()-strlen(calc_result_display)-2, 3);
207 oled_write_char(calc_operator_display, false);
208 } else if (calc_display_lines == 2) {
209 oled_set_cursor(oled_max_chars()-strlen(calc_status_display), 2);
210 oled_write(calc_status_display, false);
211 }
212 oled_set_cursor(oled_max_chars()-strlen(calc_result_display), 3);
213 oled_write(calc_result_display, false);
214 }
215}
216
217static void render_logo(void) {
218 oled_write_raw_P(raw_logo, sizeof(raw_logo));
219}
220
221void render_frame(void) {
222 if (oled_logo_expired) {
223 if (oled_mode == OLED_MODE_DEFAULT) {
224 render_mode_section();
225 render_layer_section();
226 render_encoder_section();
227 render_numlock_section();
228 } else if (oled_mode == OLED_MODE_CALC) {
229 render_mode_section();
230 render_calc_section();
231 } else if (oled_mode == OLED_MODE_OFF) {
232 if (is_oled_on()) {
233 oled_off();
234 }
235 }
236 } else {
237 render_logo();
238 oled_logo_expired = timer_elapsed(oled_logo_timer) > OLED_LOGO_TIMEOUT;
239 }
240}
241
242__attribute__((weak)) void oled_task_user(void) {
243 if (timer_elapsed(oled_frame_timer) > OLED_FRAME_TIMEOUT) {
244 oled_clear();
245 oled_frame_timer = timer_read();
246 render_frame();
247 }
248
249 if (get_highest_layer(layer_state) == 1) {
250 oled_mode = OLED_MODE_CALC;
251 } else if (get_highest_layer(layer_state) == 2) {
252 if (IS_LAYER_ON(1)) {
253 oled_mode = OLED_MODE_CALC;
254 } else {
255 oled_mode = OLED_MODE_DEFAULT;
256 }
257 } else if (get_highest_layer(layer_state) == 3) {
258 oled_mode = OLED_MODE_OFF;
259 } else {
260 oled_mode = OLED_MODE_DEFAULT;
261 }
262}
263
264oled_rotation_t oled_init_user(oled_rotation_t rotation) {
265 oled_logo_timer = timer_read();
266 oled_frame_timer = timer_read();
267 return rotation;
268}
diff --git a/keyboards/rubi/lib/oled.h b/keyboards/rubi/lib/oled.h
new file mode 100644
index 000000000..1737541c9
--- /dev/null
+++ b/keyboards/rubi/lib/oled.h
@@ -0,0 +1,32 @@
1/*
2Copyright 2021 gregorio
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#define OLED_FRAME_TIMEOUT (1000 / 30) // 30 fps
21#define OLED_LOGO_TIMEOUT 3000 // 3 sec
22
23static uint16_t oled_frame_timer = 0;
24static uint16_t oled_logo_timer = 0;
25static bool oled_logo_expired = false;
26
27static const char PROGMEM raw_logo[] = {
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,128,128,128,128, 0, 0, 0, 0, 0, 0, 0,128,128,128,128,128,128,128,128,128,128,128, 0, 0, 0, 0, 0, 0,128,128,128,128, 0, 0, 0, 0, 0, 0,128,128,128,128, 0, 0,128,128,128,128,128,128,128,128,128,128,128, 0, 0, 0, 0, 0,128,128,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,224,112,184,220,204,182,123,254,251,187,223,231,203,126,254, 0, 0, 0, 0, 0, 0,255, 0, 0, 0,248, 8, 8, 8, 8, 8,249,225, 2, 12,248, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0,255,255,255,255, 0, 0,255,255,255,255,199,199,199,199,199,207,255,255,254,124, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,127,191,188,211,223,223,247,187,187,252,126,123,247,239,223,190,115,142, 0, 0, 0, 0, 0,255, 0, 0, 0,227, 34, 34, 34, 98,194, 1, 56,236,135, 1, 0, 0, 31, 63,127,255,248,240,240,240,240,248,255,127, 63, 31, 0, 0,255,255,255,255,227,227,227,227,227,243,255,255,127, 62, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32};
diff --git a/keyboards/rubi/readme.md b/keyboards/rubi/readme.md
new file mode 100644
index 000000000..b46487cfb
--- /dev/null
+++ b/keyboards/rubi/readme.md
@@ -0,0 +1,23 @@
1# Rubi
2
3![Rubi](https://i.imgur.com/XUzxe0rh.jpg)
4
5[Proto Album](https://imgur.com/a/QVtU7hV)
6
7A 4x5 layout numpad with rotary encoder, LED indicator and OLED screen, featuring a basic calculator inside the OLED screen. The PCB supports both hotswap and solderable switch. Currently the PCB and case can only be purchased in Indonesia.
8
9* Keyboard Maintainer: [ohchiko](https://github.com/ohchiko)
10* Hardware Supported: Rubi PCB Rev. A, ATMega32u4
11* Hardware Availability: Local Indonesia GB.
12
13Make example for this keyboard (after setting up your build environment):
14
15 make rubi:default
16
17Flashing example for this keyboard:
18
19 make rubi:default:flash
20
21To put this keyboard into bootloader mode (for flashing firmware), simply activate layer 3 and press the middle key (key "5" on the proto picture) on the default keymap.
22
23See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/rubi/rubi.c b/keyboards/rubi/rubi.c
new file mode 100644
index 000000000..6cdf8302c
--- /dev/null
+++ b/keyboards/rubi/rubi.c
@@ -0,0 +1,108 @@
1/* Copyright 2021 gregorio
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "rubi.h"
17
18uint8_t oled_mode = OLED_MODE_DEFAULT;
19
20char calc_result_display[CALC_DIGITS+1] = "";
21char calc_operator_display = ' ';
22char calc_status_display[CALC_DIGITS+1] = "";
23uint8_t calc_display_lines = 2;
24
25const char keycode_to_ascii_lut[58] = {0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, '\t', ' ', '-', '=', '[', ']', '\\', 0, ';', '\'', '`', ',', '.', '/'};
26
27uint8_t encoder_mode = ENC_MODE_VOLUME;
28
29bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
30 if (keycode < 58 && keycode != KC_TAB) {
31 if (record->event.pressed) {
32 calcInput(keycode_to_ascii_lut[(uint8_t)keycode]);
33 }
34 return false;
35 }
36 switch (keycode) {
37 case ENC_PRESS:
38 if (record->event.pressed) {
39 uint16_t mapped_code = handle_encoder_press();
40 if (mapped_code != 0) {
41 tap_code16(mapped_code);
42 }
43 }
44 return false;
45 case CL_PLUS:
46 if (record->event.pressed) {
47 calcInput('+');
48 }
49 return false;
50 case CL_STAR:
51 if (record->event.pressed) {
52 calcInput('*');
53 }
54 return false;
55 case CL_TYPE:
56 if (record->event.pressed) {
57 send_string(calc_result_display);
58 }
59 return false;
60 default:
61 break;
62 }
63
64 return process_record_user_oled(keycode, record);
65}
66
67
68bool led_update_kb(led_t led_state) {
69 bool res = led_update_user(led_state);
70 if (res) {
71 writePin(C6, led_state.num_lock);
72 }
73 return true;
74}
75
76__attribute__ ((weak)) void encoder_update_user(uint8_t index, bool clockwise) {
77 if (index == 0) {
78 if (get_highest_layer(layer_state) == 0) {
79 uint16_t mapped_code = 0;
80 if (clockwise) {
81 mapped_code = handle_encoder_cw();
82 } else {
83 mapped_code = handle_encoder_ccw();
84 }
85 if (mapped_code != 0) {
86 tap_code16(mapped_code);
87 }
88 } else {
89 if (clockwise) {
90 if (oled_mode == OLED_MODE_CALC) {
91 handle_encoder_cw();
92 } else if (oled_mode == OLED_MODE_DEFAULT) {
93 change_encoder_mode(false);
94 }
95 } else {
96 if (oled_mode == OLED_MODE_CALC) {
97 handle_encoder_ccw();
98 } else if (oled_mode == OLED_MODE_DEFAULT) {
99 change_encoder_mode(true);
100 }
101 }
102 }
103 }
104}
105
106void encoder_update_kb(uint8_t index, bool clockwise) {
107 encoder_update_user(index, clockwise);
108}
diff --git a/keyboards/rubi/rubi.h b/keyboards/rubi/rubi.h
new file mode 100644
index 000000000..472ce8e00
--- /dev/null
+++ b/keyboards/rubi/rubi.h
@@ -0,0 +1,102 @@
1/* Copyright 2021 gregorio
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include "quantum.h"
19
20#define CALC_DIGITS 12
21
22enum rubi_keycodes {
23 ENC_PRESS = SAFE_RANGE,
24 CL_PLUS,
25 CL_STAR,
26 CL_TYPE,
27 NEW_SAFE_RANGE
28};
29
30enum oled_modes {
31 OLED_MODE_DEFAULT,
32 OLED_MODE_CALC,
33 OLED_MODE_OFF,
34 _NUM_OLED_MODES
35};
36
37enum encoder_modes {
38 ENC_MODE_VOLUME,
39 ENC_MODE_MEDIA,
40 ENC_MODE_BRIGHTNESS,
41 _NUM_ENCODER_MODES
42};
43
44extern uint8_t current_layer;
45extern uint8_t oled_mode;
46extern uint8_t encoder_mode;
47
48extern char calc_result_display[CALC_DIGITS+1];
49extern char calc_operator_display;
50extern char calc_status_display[CALC_DIGITS+1];
51extern uint8_t calc_display_lines;
52
53bool process_record_user_oled(uint16_t keycode, keyrecord_t *record);
54void change_oled_mode(void);
55
56void change_encoder_mode(bool reverse);
57uint16_t handle_encoder_cw(void);
58uint16_t handle_encoder_ccw(void);
59uint16_t handle_encoder_press(void);
60
61void calcUpdate(void);
62void calcInput(char input);
63void calcOperands(void);
64
65/* This is a shortcut to help you visually see your layout.
66 *
67 * The first section contains all of the arguments representing the physical
68 * layout of the board and position of the keys.
69 *
70 * The second converts the arguments into a two-dimensional array which
71 * represents the switch matrix.
72 */
73
74/* Rubi matrix layout
75 * ,---------------.
76 * | 23|
77 * |---------------|
78 * | 00| 01| 02| 03|
79 * |---------------|
80 * | 10| 11| 12| |
81 * |-----------| 13|
82 * | 20| 21| 22| |
83 * |---------------|
84 * | 30| 31| 32| |
85 * |-----------| 33|
86 * | 41 | 42| |
87 * `---------------'
88 */
89#define LAYOUT( \
90 k23, \
91 k00, k01, k02, k03, \
92 k10, k11, k12, k13, \
93 k20, k21, k22, \
94 k30, k31, k32, k33, \
95 k41, k42 \
96) { \
97 { k00, k01, k02, k03 }, \
98 { k10, k11, k12, k13 }, \
99 { k20, k21, k22, k23 }, \
100 { k30, k31, k32, k33 }, \
101 { KC_NO, k41, k42, KC_NO } \
102}
diff --git a/keyboards/rubi/rules.mk b/keyboards/rubi/rules.mk
new file mode 100644
index 000000000..59ba4ffa1
--- /dev/null
+++ b/keyboards/rubi/rules.mk
@@ -0,0 +1,28 @@
1# MCU name
2MCU = atmega32u4
3
4# Bootloader selection
5BOOTLOADER = atmel-dfu
6
7# Build Options
8# change yes to no to disable
9#
10BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
11MOUSEKEY_ENABLE = no # Mouse keys
12EXTRAKEY_ENABLE = yes # Audio control and System control
13CONSOLE_ENABLE = no # Console for debug
14COMMAND_ENABLE = no # Commands for debug and configuration
15# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
16SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
17# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
18NKRO_ENABLE = yes # USB Nkey Rollover
19BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
20RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
21BLUETOOTH_ENABLE = no # Enable Bluetooth
22AUDIO_ENABLE = no # Audio output
23OLED_DRIVER_ENABLE = yes
24ENCODER_ENABLE = yes
25
26SRC += lib/oled.c \
27 lib/encoder.c \
28 lib/calc.c