From 4caceb3617219733bff6e60e71fa405e584b552d Mon Sep 17 00:00:00 2001 From: Kymkim Date: Tue, 1 Jul 2025 15:13:32 -0700 Subject: [PATCH] 4key miku keyboard with nkro --- .../mainboard/stmf446retx/Inc/main.h | 135 ++++++++++++++++++ .../mainboard/stmf446retx/Src/gpio.c | 6 +- .../mainboard/stmf446retx/Src/main.c | 69 +++++---- 3 files changed, 171 insertions(+), 39 deletions(-) diff --git a/firmware/components/mainboard/stmf446retx/Inc/main.h b/firmware/components/mainboard/stmf446retx/Inc/main.h index be9a3f3e..5b906fa0 100644 --- a/firmware/components/mainboard/stmf446retx/Inc/main.h +++ b/firmware/components/mainboard/stmf446retx/Inc/main.h @@ -46,6 +46,141 @@ extern "C" { /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ +// Modifier Keys +#define KEY_LEFT_CTRL 0xE0 +#define KEY_LEFT_SHIFT 0xE1 +#define KEY_LEFT_ALT 0xE2 +#define KEY_LEFT_GUI 0xE3 +#define KEY_RIGHT_CTRL 0xE4 +#define KEY_RIGHT_SHIFT 0xE5 +#define KEY_RIGHT_ALT 0xE6 +#define KEY_RIGHT_GUI 0xE7 + +// Regular Keys (Usage ID 0x04–0x73) +#define KEY_A 0x04 +#define KEY_B 0x05 +#define KEY_C 0x06 +#define KEY_D 0x07 +#define KEY_E 0x08 +#define KEY_F 0x09 +#define KEY_G 0x0A +#define KEY_H 0x0B +#define KEY_I 0x0C +#define KEY_J 0x0D +#define KEY_K 0x0E +#define KEY_L 0x0F +#define KEY_M 0x10 +#define KEY_N 0x11 +#define KEY_O 0x12 +#define KEY_P 0x13 +#define KEY_Q 0x14 +#define KEY_R 0x15 +#define KEY_S 0x16 +#define KEY_T 0x17 +#define KEY_U 0x18 +#define KEY_V 0x19 +#define KEY_W 0x1A +#define KEY_X 0x1B +#define KEY_Y 0x1C +#define KEY_Z 0x1D + +#define KEY_1 0x1E +#define KEY_2 0x1F +#define KEY_3 0x20 +#define KEY_4 0x21 +#define KEY_5 0x22 +#define KEY_6 0x23 +#define KEY_7 0x24 +#define KEY_8 0x25 +#define KEY_9 0x26 +#define KEY_0 0x27 + +#define KEY_ENTER 0x28 +#define KEY_ESC 0x29 +#define KEY_BACKSPACE 0x2A +#define KEY_TAB 0x2B +#define KEY_SPACE 0x2C +#define KEY_MINUS 0x2D +#define KEY_EQUAL 0x2E +#define KEY_LEFT_BRACKET 0x2F +#define KEY_RIGHT_BRACKET 0x30 +#define KEY_BACKSLASH 0x31 +#define KEY_NON_US_HASH 0x32 +#define KEY_SEMICOLON 0x33 +#define KEY_APOSTROPHE 0x34 +#define KEY_GRAVE 0x35 +#define KEY_COMMA 0x36 +#define KEY_PERIOD 0x37 +#define KEY_SLASH 0x38 +#define KEY_CAPS_LOCK 0x39 + +// Function Keys +#define KEY_F1 0x3A +#define KEY_F2 0x3B +#define KEY_F3 0x3C +#define KEY_F4 0x3D +#define KEY_F5 0x3E +#define KEY_F6 0x3F +#define KEY_F7 0x40 +#define KEY_F8 0x41 +#define KEY_F9 0x42 +#define KEY_F10 0x43 +#define KEY_F11 0x44 +#define KEY_F12 0x45 + +#define KEY_PRINT_SCREEN 0x46 +#define KEY_SCROLL_LOCK 0x47 +#define KEY_PAUSE 0x48 + +// Navigation Keys +#define KEY_INSERT 0x49 +#define KEY_HOME 0x4A +#define KEY_PAGE_UP 0x4B +#define KEY_DELETE 0x4C +#define KEY_END 0x4D +#define KEY_PAGE_DOWN 0x4E + +#define KEY_RIGHT_ARROW 0x4F +#define KEY_LEFT_ARROW 0x50 +#define KEY_DOWN_ARROW 0x51 +#define KEY_UP_ARROW 0x52 + +// Keypad +#define KEY_NUM_LOCK 0x53 +#define KEYPAD_SLASH 0x54 +#define KEYPAD_ASTERISK 0x55 +#define KEYPAD_MINUS 0x56 +#define KEYPAD_PLUS 0x57 +#define KEYPAD_ENTER 0x58 +#define KEYPAD_1 0x59 +#define KEYPAD_2 0x5A +#define KEYPAD_3 0x5B +#define KEYPAD_4 0x5C +#define KEYPAD_5 0x5D +#define KEYPAD_6 0x5E +#define KEYPAD_7 0x5F +#define KEYPAD_8 0x60 +#define KEYPAD_9 0x61 +#define KEYPAD_0 0x62 +#define KEYPAD_DOT 0x63 + +// Misc/Non-US +#define KEY_NON_US_BACKSLASH 0x64 +#define KEY_APPLICATION 0x65 +#define KEY_POWER 0x66 +#define KEYPAD_EQUAL 0x67 +#define KEY_F13 0x68 +#define KEY_F14 0x69 +#define KEY_F15 0x6A +#define KEY_F16 0x6B +#define KEY_F17 0x6C +#define KEY_F18 0x6D +#define KEY_F19 0x6E +#define KEY_F20 0x6F +#define KEY_F21 0x70 +#define KEY_F22 0x71 +#define KEY_F23 0x72 +#define KEY_F24 0x73 /* USER CODE END EM */ diff --git a/firmware/components/mainboard/stmf446retx/Src/gpio.c b/firmware/components/mainboard/stmf446retx/Src/gpio.c index d5a5c900..1ba0cb9a 100644 --- a/firmware/components/mainboard/stmf446retx/Src/gpio.c +++ b/firmware/components/mainboard/stmf446retx/Src/gpio.c @@ -56,20 +56,20 @@ void MX_GPIO_Init(void) /*Configure GPIO pins : PB13 PB14 */ GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PB15 */ GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PC6 */ GPIO_InitStruct.Pin = GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } diff --git a/firmware/components/mainboard/stmf446retx/Src/main.c b/firmware/components/mainboard/stmf446retx/Src/main.c index 5f4c4dea..a993c90c 100644 --- a/firmware/components/mainboard/stmf446retx/Src/main.c +++ b/firmware/components/mainboard/stmf446retx/Src/main.c @@ -33,21 +33,14 @@ typedef struct{ uint8_t MODIFIER; uint8_t RESERVED; - uint8_t KEYSTATUS[13]; + uint8_t KEYPRESS[13]; } HIDReport; typedef struct{ - uint16_t PORT; + GPIO_TypeDef* PORT; uint16_t PIN; } KbdPins; -typedef struct{ - uint8_t PREV; //Previous State - uint8_t CURR; //Current State - uint8_t KEYCODE; -} Key; - - extern USBD_HandleTypeDef hUsbDeviceFS; /* USER CODE END PTD */ @@ -65,9 +58,9 @@ extern USBD_HandleTypeDef hUsbDeviceFS; /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ -Key matrix[ROWS][COLS] = { - {{0,0,0x01},{0,0,0x0C}}, - {{0,0,0x0E},{0,0,0x18}}, +uint8_t matrix[ROWS][COLS] = { + {KEY_M, KEY_K}, + {KEY_I, KEY_U} }; KbdPins row_pins[ROWS] = { {GPIOC, GPIO_PIN_6}, @@ -77,12 +70,13 @@ KbdPins col_pins[COLS] = { {GPIOB, GPIO_PIN_14}, {GPIOB, GPIO_PIN_13} }; +HIDReport REPORT = {0,0,0,0,0,0,0,0}; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ - +void addHIDReport(uint8_t usageID, uint8_t isPressed); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ @@ -98,8 +92,6 @@ int main(void) { /* USER CODE BEGIN 1 */ - HIDReport report = {0,0,0,0,0,0,0,0}; - uint8_t report_buff[] = {0,0,0,0,0,0}; /* USER CODE END 1 */ @@ -131,33 +123,26 @@ int main(void) /* USER CODE BEGIN WHILE */ while (1) { - //Keycode Scan - // for(int col = 0; col < COLS; col++){ - // HAL_GPIO_WritePin(col_pins[col].PORT, col_pins[col].PIN, GPIO_PIN_SET); - // for(int row = 0; row < ROWS; row++){ - // uint8_t state = HAL_GPIO_ReadPin(row_pins[row].PORT, col_pins[row].PIN); - // if(state != matrix[row][col].PREV){ - // matrix[row][col].PREV = matrix[row][col].CURR; - // matrix[row][col].CURR = state; - // if(state){ - // //Put into the buffer - // if(report_buff) - // } - // } - - // } - // } - /* USER CODE END WHILE */ - report.KEYSTATUS[0] = 0x01; - USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)&report, sizeof(report)); - HAL_Delay(1000); + for(int col = 0; col < COLS; col++){ + HAL_GPIO_WritePin(col_pins[col].PORT, col_pins[col].PIN, GPIO_PIN_SET); + HAL_Delay(1); + for(int row = 0; row < ROWS; row++){ + if(HAL_GPIO_ReadPin(row_pins[row].PORT, row_pins[row].PIN)){ + addHIDReport(matrix[row][col], 1); + }else{ + addHIDReport(matrix[row][col], 0); + } + } + HAL_GPIO_WritePin(col_pins[col].PORT, col_pins[col].PIN, GPIO_PIN_RESET); + } + USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)&REPORT, sizeof(REPORT)); + HAL_Delay(20); /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } - /** * @brief System Clock Configuration * @retval None @@ -205,7 +190,19 @@ void SystemClock_Config(void) } /* USER CODE BEGIN 4 */ +//Converts UsageID to NKRO bit field and add it to the report +void addHIDReport(uint8_t usageID, uint8_t isPressed){ + if(usageID < 0x04 || usageID > 0x73) return; //Usage ID is out of bounds + uint16_t bit_index = usageID - 0x04; //Offset, UsageID starts with 0x04. Gives us the actual value of the bit + uint8_t byte_index = bit_index/8; //Calculates which byte in the REPORT array + uint8_t bit_offset = bit_index%8; //Calculates which bits in the REPORT[byte_index] should be set/unset + if(isPressed){ + REPORT.KEYPRESS[byte_index] |= (1 << bit_offset); + }else{ + REPORT.KEYPRESS[byte_index] &= ~(1 << bit_offset); + } +} /* USER CODE END 4 */ /**