Added Audio to my Atomic
6 files changed, 297 insertions(+), 175 deletions(-) M keyboard/atomic/Makefile A keyboard/atomic/keymaps/pvc/config.h R keyboard/atomic/keymaps/pvc/{pvc_atomic => keymap}.c M keyboard/atomic/keymaps/pvc/makefile.mk M keyboard/planck/Makefile M quantum/audio.h
M keyboard/atomic/Makefile => keyboard/atomic/Makefile +39 -28
@@ 38,31 38,9 @@ # To rebuild project do "make clean" then "make all". #---------------------------------------------------------------------------- # Build Options # change to "no" to disable the options, or define them in the makefile.mk in # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = no # USB Nkey Rollover - if this doesn't work, see here: # https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # Target file name (without extension). TARGET = atomic # Directory common source filess exist TOP_DIR = ../.. @@ TMK_DIR = ../../tmk_core 73,6 51,8 @@ TARGET_DIR = . # # project specific files SRC = atomic.c CONFIG_H = config.h ifdef keymap KEYMAP = $(keymap) @@ endif 88,7 68,7 @@ ifneq ("$(wildcard keymaps/$(KEYMAP)/makefile.mk)","") endif else $(error Keymap file does not exist) endif endif endif @@ else 107,8 87,6 @@ endif SRC := $(KEYMAP_FILE) $(SRC) CONFIG_H = config.h # MCU name #MCU = at90usb1287 @@ MCU = atmega32u4 126,7 104,6 @@ MCU = atmega32u4 # software delays. F_CPU = 16000000 # # LUFA specific @@ # 158,11 135,45 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT # USBaspLoader 2048 OPT_DEFS += -DBOOTLOADER_SIZE=4096 # Build Options # change to "no" to disable the options, or define them in the makefile.mk in # the appropriate keymap folder that will get included automatically # BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend ifdef KEYMAP ifeq ("$(wildcard keymaps/$(KEYMAP).c)","") ifneq ("$(wildcard keymaps/$(KEYMAP)/makefile.mk)","") include keymaps/$(KEYMAP)/makefile.mk endif endif else ifneq ("$(wildcard keymaps/default/makefile.mk)","") include keymaps/default/makefile.mk endif ifeq ($(BACKLIGHT_ENABLE), yes) SRC += backlight.c endif ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) SRC := backlight.c $(SRC) endif # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax
A keyboard/atomic/keymaps/pvc/config.h => keyboard/atomic/keymaps/pvc/config.h +157 -0
@@ 0,0 1,157 @@ /* Copyright 2012 Jun Wako <wakojun@gmail.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef CONFIG_H #define CONFIG_H #include "config_common.h" /* USB Device descriptor parameter */ #define VENDOR_ID 0xFEED #define PRODUCT_ID 0x6060 #define DEVICE_VER 0x0001 #define MANUFACTURER Ortholinear Keyboards #define PRODUCT The Atomic Keyboard #define DESCRIPTION A compact ortholinear keyboard /* key matrix size */ #define MATRIX_ROWS 5 #define MATRIX_COLS 15 /* * Keyboard Matrix Assignments * * Change this to how you wired your keyboard * COLS: AVR pins used for columns, left to right * ROWS: AVR pins used for rows, top to bottom * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * */ #define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7, D3, D2, D1 } #define ROWS (int []){ D0, D5, B5, B6, B3 } /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCE 5 /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST /* number of backlight levels */ #define BACKLIGHT_LEVELS 3 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE /* * Force NKRO * * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the * makefile for this to work.) * * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) * until the next keyboard reset. * * NKRO may prevent your keystrokes from being detected in the BIOS, but it is * fully operational during normal computer usage. * * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by * bootmagic, NKRO mode will always be enabled until it is toggled again during a * power-up. * */ //#define FORCE_NKRO /* * Magic Key Options * * Magic keys are hotkey commands that allow control over firmware functions of * the keyboard. They are best used in combination with the HID Listen program, * found here: https://www.pjrc.com/teensy/hid_listen.html * * The options below allow the magic key functionality to be changed. This is * useful if your keyboard/keypad is missing keys and you want magic key support. * */ /* key combination for magic key command */ #define IS_COMMAND() ( \ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ ) /* control how magic key switches layers */ //#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true //#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true //#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false /* override magic key keymap */ //#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS //#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS //#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM //#define MAGIC_KEY_HELP1 H //#define MAGIC_KEY_HELP2 SLASH //#define MAGIC_KEY_DEBUG D //#define MAGIC_KEY_DEBUG_MATRIX X //#define MAGIC_KEY_DEBUG_KBD K //#define MAGIC_KEY_DEBUG_MOUSE M //#define MAGIC_KEY_VERSION V //#define MAGIC_KEY_STATUS S //#define MAGIC_KEY_CONSOLE C //#define MAGIC_KEY_LAYER0_ALT1 ESC //#define MAGIC_KEY_LAYER0_ALT2 GRAVE //#define MAGIC_KEY_LAYER0 0 //#define MAGIC_KEY_LAYER1 1 //#define MAGIC_KEY_LAYER2 2 //#define MAGIC_KEY_LAYER3 3 //#define MAGIC_KEY_LAYER4 4 //#define MAGIC_KEY_LAYER5 5 //#define MAGIC_KEY_LAYER6 6 //#define MAGIC_KEY_LAYER7 7 //#define MAGIC_KEY_LAYER8 8 //#define MAGIC_KEY_LAYER9 9 #define MAGIC_KEY_BOOTLOADER B //#define MAGIC_KEY_LOCK CAPS //#define MAGIC_KEY_EEPROM E //#define MAGIC_KEY_NKRO N //#define MAGIC_KEY_SLEEP_LED Z /* * Feature disable options * These options are also useful to firmware size reduction. */ /* disable debug print */ //#define NO_DEBUG /* disable print */ //#define NO_PRINT /* disable action features */ //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT //#define NO_ACTION_MACRO //#define NO_ACTION_FUNCTION #endif
R keyboard/atomic/keymaps/pvc/pvc_atomic.c => keyboard/atomic/keymaps/pvc/keymap.c +94 -113
@@ 1,12 1,19 @@ #include "atomic.h" #include "action_layer.h" #ifdef AUDIO_ENABLE #include "audio.h" #endif #define _QW 0 #define _LW 1 #define _RS 2 #define _FN 3 #define _F1 4 #define _F2 5 #define M_QW 0 #define M_LW 1 #define M_RS 2 #define M_FN 3 #define _______ KC_TRNS @@ #define ___T___ KC_TRNS 32,7 39,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL }, { KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, XXXXXXX, KC_PGUP }, { KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, XXXXXXX, KC_UP, KC_PGDN }, { KC_LCTL, KC_LGUI, M(_FN), KC_LALT, M(_RS), KC_SPC, XXXXXXX, M(_LW), KC_RALT, KC_HOME, KC_END, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT }, { KC_LCTL, KC_LGUI, M(M_FN), KC_LALT, M(M_RS), KC_SPC, XXXXXXX, M(M_LW), KC_RALT, KC_HOME, KC_END, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT }, }, [_LW] = { /* LOWERED */ @@ { KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ___T___, ___T___ }, 55,29 62,50 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { { _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, ___T___, ___T___, KC_MS_U, KC_WH_D }, { _______, _______, _______, _______, _______, KC_BTN1, KC_BTN1, _______, _______, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R }, }, [_F1] = { /* FUNCTION */ { KC_NLCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ___T___, ___T___ }, { KC_SLCK, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_F24, KC_PAUS, KC_PSCR }, { KC_CAPS, KC_BTN5, KC_BTN4, KC_BTN3, KC_BTN2, KC_ACL0, KC_ACL2, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, ___T___, ___T___, KC_WH_U }, { _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, ___T___, ___T___, KC_MS_U, KC_WH_D }, { _______, _______, _______, _______, _______, KC_BTN1, KC_BTN1, _______, _______, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R }, }, [_F2] = { /* FUNCTION */ { KC_NLCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ___T___, ___T___ }, { KC_SLCK, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_F24, KC_PAUS, KC_PSCR }, { KC_CAPS, KC_BTN5, KC_BTN4, KC_BTN3, KC_BTN2, KC_ACL0, KC_ACL2, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, ___T___, ___T___, KC_WH_U }, { _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, ___T___, ___T___, KC_MS_U, KC_WH_D }, { _______, _______, _______, _______, _______, KC_BTN1, KC_BTN1, _______, _______, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R }, }, }; #define IS_LAYER_ON(layer) ((layer_state) & (1<<(layer))) #define IS_LAYER_OFF(layer) ((!layer_state) & (1<<(layer))) #ifdef AUDIO_ENABLE float tone_lw[][2] = { {440.0*pow(2.0,(59)/12.0), 8}, {440.0*pow(2.0,(60)/12.0), 8}, {0, 4}, {440.0*pow(2.0,(67)/12.0), 16} }; float tone_rs[][2] = { {440.0*pow(2.0,(59)/12.0), 8}, {440.0*pow(2.0,(60)/12.0), 8}, {0, 4}, {440.0*pow(2.0,(67)/12.0), 16}, {0, 4}, {440.0*pow(2.0,(71)/12.0), 16} }; float tone_fn[][2] = { {440.0*pow(2.0,(59)/12.0), 8}, {440.0*pow(2.0,(60)/12.0), 8}, {0, 4}, {440.0*pow(2.0,(67)/12.0), 16}, {0, 4}, {440.0*pow(2.0,(69)/12.0), 16}, {0, 4}, {440.0*pow(2.0,(67)/12.0), 16} }; #endif void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { #ifdef AUDIO_ENABLE println("PlayNotes FN"); play_notes(&tone_fn, 8, false); #endif layer_on(layer3); } @@ else 114,37 142,6 @@ void update_quad_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3, uint8_t l } } /* ignore me void change_quad_layer(uint8_t focus_layer, bool desired_focus_layer_state, uint8_t pair_layer, uint8_t layer3, uint8_t layer4) { // If desired focus layer state == 1 and current focus layer state == 1 if ((desired_focus_layer_state) && IS_LAYER_ON(layer1)) { // Do Nothing } // If desired focus layer state == 0 and current focus layer state == 1 else if ((desired_focus_layer_state) && IS_LAYER_ON(layer1)) { // If layer_off(layer3); layer_off(layer4); } } else { if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) { layer_on(layer4); } else { layer_off(layer3); layer_off(layer4); } } } */ const uint16_t PROGMEM fn_actions[] = { @@ }; 152,70 149,54 @@ const uint16_t PROGMEM fn_actions[] = { const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { // MACRODOWN only works in this function switch(id) { case _FN: if (record->event.pressed) { print("FN_DN\n"); print_val_bin32(layer_state); layer_on(_FN); print_val_bin32(layer_state); } else { print("FN_UP\n"); print_val_bin32(layer_state); layer_off(_FN); print_val_bin32(layer_state); } break; case _RS: if (record->event.pressed) { print("RS_DN\n"); print_val_bin32(layer_state); layer_on(_RS); //tri_layer++; print_val_bin32(layer_state); //update_tri_layer(_RS, _LW, _FN); update_quad_layer(_RS, _LW, _F1, _F2, 0); print_val_bin32(layer_state); } else { print("RS_UP\n"); print_val_bin32(layer_state); layer_off(_RS); //tri_layer--; print_val_bin32(layer_state); //update_tri_layer(_RS, _LW, _FN); update_quad_layer(_RS, _LW, _F1, _F2, 0); print_val_bin32(layer_state); } break; case _LW: if (record->event.pressed) { print("LW_DN\n"); print_val_bin32(layer_state); layer_on(_LW); //tri_layer++; print_val_bin32(layer_state); //update_tri_layer(_RS, _LW, _FN); update_quad_layer(_RS, _LW, _F1, _F2, 1); print_val_bin32(layer_state); } else { print("LW_UP\n"); print_val_bin32(layer_state); layer_off(_LW); //tri_layer--; print_val_bin32(layer_state); //update_tri_layer(_RS, _LW, _FN); update_quad_layer(_RS, _LW, _F1, _F2, 1); print_val_bin32(layer_state); } break; // MACRODOWN only works in this function switch(id) { case M_LW: if (record->event.pressed) { #ifdef AUDIO_ENABLE println("PlayNotes LW"); play_notes(&tone_lw, 4, false); #endif layer_on(_LW); update_tri_layer(_LW, _RS, _FN); } else { layer_off(_LW); update_tri_layer(_LW, _RS, _FN); } break; case M_RS: if (record->event.pressed) { #ifdef AUDIO_ENABLE println("PlayNotes RS"); play_notes(&tone_rs, 6, false); #endif layer_on(_RS); update_tri_layer(_LW, _RS, _FN); } else { layer_off(_RS); update_tri_layer(_LW, _RS, _FN); } break; default: break; } return MACRO_NONE; break; } return MACRO_NONE; }; #ifdef AUDIO_ENABLE float start_up[][2] = { {440.0*pow(2.0,(67)/12.0), 12}, {440.0*pow(2.0,(64)/12.0), 8}, {440.0*pow(2.0,(55)/12.0), 8}, {440.0*pow(2.0,(60)/12.0), 8}, {440.0*pow(2.0,(64)/12.0), 20} }; #endif void matrix_init_user(void) { #ifdef AUDIO_ENABLE init_notes(); play_notes(&start_up, 5, false); println("Matrix Init"); #endif }
M keyboard/atomic/keymaps/pvc/makefile.mk => keyboard/atomic/keymaps/pvc/makefile.mk +4 -2
@@ 1,16 1,18 @@ BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: # https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 AUDIO_ENABLE = yes # Audio output on port C6 UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend CONFIG_H = keymaps/$(KEYMAP)/config.h \ No newline at end of file
M keyboard/planck/Makefile => keyboard/planck/Makefile +1 -30
@@ 157,39 157,10 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend ifdef KEYMAP <<<<<<< HEAD <<<<<<< HEAD # Build Options # comment out to disable the options. # BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = yes # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work # BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality # MIDI_ENABLE = yes # MIDI controls # AUDIO_ENABLE = yes # Audio output on port C6 # UNICODE_ENABLE = yes # Unicode # BLUETOOTH_ENABLE = ye # Enable Bluetooth with the Adafruit EZ-Key HID # RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE #SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend ifdef BACKLIGHT_ENABLE ======= ifeq ($(BACKLIGHT_ENABLE), yes) >>>>>>> master SRC += backlight.c ======= ifeq ("$(wildcard keymaps/$(KEYMAP).c)","") ifneq ("$(wildcard keymaps/$(KEYMAP)/makefile.mk)","") include keymaps/$(KEYMAP)/makefile.mk endif >>>>>>> remotes/jackhumbert/new_defaults endif @@ else 212,4 183,4 @@ VPATH += $(TARGET_DIR) VPATH += $(TOP_DIR) VPATH += $(TMK_DIR) include $(TOP_DIR)/quantum/quantum.mk include $(TOP_DIR)/quantum/quantum.mk \ No newline at end of file
M quantum/audio.h => quantum/audio.h +2 -2
@@ 6,6 6,6 @@ void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); void stop_all_notes(); void init_notes(); void stop_all_notes(void); void init_notes(void); void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); \ No newline at end of file