Some work on the GPIO, enabled DMA for TX as well
This commit is contained in:
0
firmware/core/Core/Inc/keys.h
Normal file
0
firmware/core/Core/Inc/keys.h
Normal file
194
firmware/core/Core/Inc/numpad.h
Normal file
194
firmware/core/Core/Inc/numpad.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __NUMPAD_H
|
||||
#define __NUMPAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ROWS 6
|
||||
#define COLS 4
|
||||
|
||||
// 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
|
||||
|
||||
typedef struct{
|
||||
GPIO_TypeDef* PORT;
|
||||
uint16_t PIN;
|
||||
} KbdPins;
|
||||
|
||||
KbdPins row_pins[ROWS] = {
|
||||
{GPIOC, GPIO_PIN_6},
|
||||
{GPIOB, GPIO_PIN_15}
|
||||
};
|
||||
KbdPins col_pins[COLS] = {
|
||||
{GPIOB, GPIO_PIN_14},
|
||||
{GPIOB, GPIO_PIN_13}
|
||||
};
|
||||
uint8_t matrix[ROWS][COLS] = {
|
||||
{KEY_0, KEY_1, KEY_2, KEY_3},
|
||||
{KEY_0, KEY_1, KEY_2, KEY_3},
|
||||
{KEY_0, KEY_1, KEY_2, KEY_3},
|
||||
{KEY_0, KEY_1, KEY_2, KEY_3},
|
||||
{KEY_0, KEY_1, KEY_2, KEY_3},
|
||||
{KEY_0, KEY_1, KEY_2, KEY_3},
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NUMPAD_H */
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "main.h"
|
||||
#include "numpad.h"
|
||||
#include "usb_device.h"
|
||||
#include "usbd_hid.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MODE_INACTIVE 0
|
||||
@@ -9,6 +11,8 @@
|
||||
|
||||
#define MODULE_HANDSHAKE_REQUEST 0x000F0000
|
||||
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
typedef struct{
|
||||
uint8_t data[4];
|
||||
} Packet;
|
||||
@@ -19,17 +23,28 @@ typedef struct {
|
||||
volatile uint16_t tail;
|
||||
} DMA_QUEUE;
|
||||
|
||||
typedef struct{
|
||||
uint8_t MODIFIER;
|
||||
uint8_t RESERVED;
|
||||
uint8_t KEYPRESS[12];
|
||||
} HIDReportNKRO;
|
||||
|
||||
DMA_QUEUE RxQueue;
|
||||
uint8_t DMA_RX_BUFFER[4];
|
||||
uint8_t DMA_RX_BUFFER_N[4];
|
||||
uint8_t DMA_RX_BUFFER_E[4];
|
||||
uint8_t DMA_RX_BUFFER_S[4];
|
||||
uint8_t DMA_RX_BUFFER_W[4];
|
||||
|
||||
I2C_HandleTypeDef hi2c1;
|
||||
TIM_HandleTypeDef htim3;
|
||||
|
||||
UART_HandleTypeDef huart4;
|
||||
UART_HandleTypeDef huart5;
|
||||
UART_HandleTypeDef huart1;
|
||||
UART_HandleTypeDef huart2;
|
||||
UART_HandleTypeDef* UART_PORTS[] = { &huart4, &huart5, &huart1, &huart2 };
|
||||
HIDReportNKRO USB_REPORT;
|
||||
|
||||
UART_HandleTypeDef huart4; //West
|
||||
UART_HandleTypeDef huart5; //North
|
||||
UART_HandleTypeDef huart1; //East
|
||||
UART_HandleTypeDef huart2; //South
|
||||
UART_HandleTypeDef* UART_PORTS[] = { &huart5, &huart1, &huart2, &huart4 };
|
||||
UART_HandleTypeDef* PARENT;
|
||||
DMA_HandleTypeDef hdma_uart4_rx;
|
||||
DMA_HandleTypeDef hdma_uart5_rx;
|
||||
@@ -48,7 +63,7 @@ static void MX_UART5_Init(void);
|
||||
static void MX_USART1_UART_Init(void);
|
||||
static void MX_USART2_UART_Init(void);
|
||||
void DMA_Queue_Init(DMA_QUEUE* q);
|
||||
|
||||
void addHIDReport(uint8_t usageID, uint8_t isPressed);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -76,14 +91,32 @@ int main(void)
|
||||
switch(CURRENT_MODE){
|
||||
|
||||
case MODE_INACTIVE:
|
||||
//TODO: Check if connected VIA USB, If so switch to master mode
|
||||
|
||||
if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) {
|
||||
CURRENT_MODE = MODE_MASTER;
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t candidates_depth[] = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
//Poll all UART Ports
|
||||
for(uint8_t i = 0; i<4; i++){
|
||||
|
||||
uint8_t rxBuffer[4] = {0};
|
||||
uint8_t msg[4] = {0x00, 0x0F, 0x00, 0x00};
|
||||
|
||||
//Send request
|
||||
HAL_UART_Transmit(UART_PORTS[i], msg, 4, HAL_MAX_DELAY);
|
||||
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
|
||||
//Await Response
|
||||
if (HAL_UART_Receive(UART_PORTS[i], rxBuffer, 4, 500) == HAL_OK) {
|
||||
//Is a type of confirmation message
|
||||
if(rxBuffer[1] == 0xFF){
|
||||
@@ -94,7 +127,11 @@ int main(void)
|
||||
} else {
|
||||
// Timeout or error
|
||||
candidates_depth[i] = 0xFF;
|
||||
}
|
||||
}
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
// Arbitration: 0xFF means invalid
|
||||
@@ -107,10 +144,30 @@ int main(void)
|
||||
best_parent = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(best_parent != 0xFF){ // found a valid parent
|
||||
PARENT = UART_PORTS[best_parent]; // assign UART handle pointer
|
||||
CURRENT_MODE = MODE_MODULE;
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
|
||||
switch(best_parent){
|
||||
case 0:
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
|
||||
break;
|
||||
case 1:
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
|
||||
break;
|
||||
case 2:
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
|
||||
break;
|
||||
case 3:
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MODE_MODULE:
|
||||
@@ -120,23 +177,59 @@ int main(void)
|
||||
|
||||
case MODE_MASTER:
|
||||
DMA_Queue_Init(&RxQueue);
|
||||
//TODO: Sending to USB and key keyscanning
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
HAL_GPIO_WritePin(col_pins[col].PORT, col_pins[col].PIN, GPIO_PIN_RESET);
|
||||
}
|
||||
//Send USB Report
|
||||
USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)&USB_REPORT, sizeof(USB_REPORT));
|
||||
|
||||
HAL_Delay(20);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
USB_REPORT.KEYPRESS[byte_index] |= (1 << bit_offset);
|
||||
}else{
|
||||
USB_REPORT.KEYPRESS[byte_index] &= ~(1 << bit_offset);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
//TODO: Handle recieved message here
|
||||
switch(CURRENT_MODE){
|
||||
case MODE_MODULE:
|
||||
|
||||
break;
|
||||
case MODE_MASTER:
|
||||
//Handle master message and add to USB_REPORT
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DMA_Queue_Init(DMA_QUEUE* q){
|
||||
q->head = 0;
|
||||
q->tail = 0;
|
||||
//Activate DMA to all ports
|
||||
for(uint8_t i = 0; i<4; i++){
|
||||
HAL_UART_Receive_DMA(UART_PORTS[i], DMA_RX_BUFFER, 4);
|
||||
}
|
||||
HAL_UART_Receive_DMA(&huart5, DMA_RX_BUFFER_N, 4);
|
||||
HAL_UART_Receive_DMA(&huart1, DMA_RX_BUFFER_E, 4);
|
||||
HAL_UART_Receive_DMA(&huart2, DMA_RX_BUFFER_S, 4);
|
||||
HAL_UART_Receive_DMA(&huart4, DMA_RX_BUFFER_W, 4);
|
||||
}
|
||||
|
||||
bool DMA_Queue_IsFull(DMA_QUEUE* q){
|
||||
@@ -406,15 +499,23 @@ static void MX_DMA_Init(void)
|
||||
/* DMA1_Stream0_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
|
||||
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);
|
||||
/* DMA1_Stream2_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
|
||||
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
|
||||
/* DMA1_Stream5_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
|
||||
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
|
||||
/* DMA2_Stream2_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
|
||||
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user