Instead of scanning the keyboard matrix from the main loop and utilizing busy loops, try to use a PIT interrupt handler to do the same thing, scanning one row per interrupt call without busy loops.

For some reason, this makes the movement of the mouse pointer very slow and makes it jump from time to time, so I ended up adding INTERRUPT_KEY_SCANNER and disabling the timer interrupt.
Also double bufferred the mouse report just like the others. Unfortunately this does not affect this issue.
This commit is contained in:
László Monda
2017-11-02 01:11:41 +01:00
parent 024f24f489
commit 00dfd96d55
15 changed files with 157 additions and 43 deletions

View File

@@ -19,7 +19,7 @@
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="uhk60-right_debug/uhk-right.hex"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="../../../scripts/update-master-firmware.js"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="../../scripts/update-master-firmware.js"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="uhk-right"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331.1297236062"/>

View File

@@ -19,7 +19,7 @@
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="uhk60-right_release/uhk-right.hex"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="../../../scripts/update-master-firmware.js"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="../../scripts/update-master-firmware.js"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="uhk-right"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1939339834.1692217331"/>

View File

@@ -4,6 +4,7 @@
// Macros:
#define I2C_WATCHDOG
// #define INTERRUPT_KEY_SCANNER
// #define LED_DRIVER_STRESS_TEST
#endif

View File

@@ -19,6 +19,7 @@ void InitInterruptPriorities(void)
NVIC_SetPriority(I2C0_IRQn, 1);
NVIC_SetPriority(I2C1_IRQn, 1);
NVIC_SetPriority(USB0_IRQn, 1);
NVIC_SetPriority(PIT1_IRQn, 6);
}
void delay(void)

View File

@@ -0,0 +1,22 @@
#include "key_matrix_instance.h"
key_matrix_t KeyMatrix = {
.colNum = KEYBOARD_MATRIX_COLS_NUM,
.rowNum = KEYBOARD_MATRIX_ROWS_NUM,
.cols = (key_matrix_pin_t[]){
{PORTA, GPIOA, kCLOCK_PortA, 5},
{PORTB, GPIOB, kCLOCK_PortB, 16},
{PORTB, GPIOB, kCLOCK_PortB, 17},
{PORTB, GPIOB, kCLOCK_PortB, 18},
{PORTB, GPIOB, kCLOCK_PortB, 19},
{PORTA, GPIOA, kCLOCK_PortA, 1},
{PORTB, GPIOB, kCLOCK_PortB, 1}
},
.rows = (key_matrix_pin_t[]){
{PORTA, GPIOA, kCLOCK_PortA, 12},
{PORTA, GPIOA, kCLOCK_PortA, 13},
{PORTC, GPIOC, kCLOCK_PortC, 1},
{PORTC, GPIOC, kCLOCK_PortC, 0},
{PORTD, GPIOD, kCLOCK_PortD, 5}
}
};

View File

@@ -0,0 +1,17 @@
#ifndef __KEY_MATRIX_INSTANCE_H__
#define __KEY_MATRIX_INSTANCE_H__
// Includes:
#include "key_matrix.h"
// Macros:
#define KEYBOARD_MATRIX_COLS_NUM 7
#define KEYBOARD_MATRIX_ROWS_NUM 5
// Variables:
extern key_matrix_t KeyMatrix;
#endif

23
right/src/key_scanner.c Normal file
View File

@@ -0,0 +1,23 @@
#include "fsl_pit.h"
#include "key_scanner.h"
#include "usb_protocol_handler.h"
uint32_t counter = 0;
void PIT_KEY_SCANNER_HANDLER(void)
{
*((uint32_t*)(UsbDebugInfo+20)) = counter++;
KeyMatrix_ScanRow(&KeyMatrix);
PIT_ClearStatusFlags(PIT, PIT_KEY_SCANNER_CHANNEL, PIT_TFLG_TIF_MASK);
}
void InitKeyScanner(void)
{
pit_config_t pitConfig;
PIT_GetDefaultConfig(&pitConfig);
PIT_Init(PIT, &pitConfig);
PIT_SetTimerPeriod(PIT, PIT_KEY_SCANNER_CHANNEL, USEC_TO_COUNT(KEY_SCANNER_INTERVAL_USEC, PIT_SOURCE_CLOCK));
PIT_EnableInterrupts(PIT, PIT_KEY_SCANNER_CHANNEL, kPIT_TimerInterruptEnable);
EnableIRQ(PIT_KEY_SCANNER_IRQ_ID);
PIT_StartTimer(PIT, PIT_KEY_SCANNER_CHANNEL);
}

21
right/src/key_scanner.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef __KEY_SCANNER_H__
#define __KEY_SCANNER_H__
// Includes:
#include "key_matrix_instance.h"
// Macros:
#define KEY_SCANNER_INTERVAL_USEC (1000 / KEYBOARD_MATRIX_ROWS_NUM)
#define PIT_KEY_SCANNER_HANDLER PIT1_IRQHandler
#define PIT_KEY_SCANNER_IRQ_ID PIT1_IRQn
#define PIT_KEY_SCANNER_CHANNEL kPIT_Chnl_1
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)
// Functions:
void InitKeyScanner(void);
#endif

View File

@@ -14,27 +14,8 @@
#include "command.h"
#include "bootloader/wormhole.h"
#include "eeprom.h"
key_matrix_t KeyMatrix = {
.colNum = KEYBOARD_MATRIX_COLS_NUM,
.rowNum = KEYBOARD_MATRIX_ROWS_NUM,
.cols = (key_matrix_pin_t[]){
{PORTA, GPIOA, kCLOCK_PortA, 5},
{PORTB, GPIOB, kCLOCK_PortB, 16},
{PORTB, GPIOB, kCLOCK_PortB, 17},
{PORTB, GPIOB, kCLOCK_PortB, 18},
{PORTB, GPIOB, kCLOCK_PortB, 19},
{PORTA, GPIOA, kCLOCK_PortA, 1},
{PORTB, GPIOB, kCLOCK_PortB, 1}
},
.rows = (key_matrix_pin_t[]){
{PORTA, GPIOA, kCLOCK_PortA, 12},
{PORTA, GPIOA, kCLOCK_PortA, 13},
{PORTC, GPIOC, kCLOCK_PortC, 1},
{PORTC, GPIOC, kCLOCK_PortC, 0},
{PORTD, GPIOD, kCLOCK_PortD, 5}
}
};
#include "key_matrix_instance.h"
#include "key_scanner.h"
uint8_t CurrentKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
@@ -44,19 +25,23 @@ void UpdateUsbReports(void)
return;
}
#ifndef INTERRUPT_KEY_SCANNER
KeyMatrix_Scan(&KeyMatrix);
#endif
memcpy(CurrentKeyStates[SlotId_RightKeyboardHalf], KeyMatrix.keyStates, MAX_KEY_COUNT_PER_MODULE);
ResetActiveUsbBasicKeyboardReport();
ResetActiveUsbMediaKeyboardReport();
ResetActiveUsbSystemKeyboardReport();
ResetActiveUsbMouseReport();
UpdateActiveUsbReports();
SwitchActiveUsbBasicKeyboardReport();
SwitchActiveUsbMediaKeyboardReport();
SwitchActiveUsbSystemKeyboardReport();
SwitchActiveUsbMouseReport();
IsUsbBasicKeyboardReportSent = false;
}
@@ -87,6 +72,9 @@ void main(void)
} else {
InitSlaveScheduler();
KeyMatrix_Init(&KeyMatrix);
#ifdef INTERRUPT_KEY_SCANNER
InitKeyScanner();
#endif
UpdateUsbReports();
InitUsb();

View File

@@ -7,14 +7,8 @@
#include "slot.h"
#include "module.h"
// Macros:
#define KEYBOARD_MATRIX_COLS_NUM 7
#define KEYBOARD_MATRIX_ROWS_NUM 5
// Variables:
extern key_matrix_t KeyMatrix;
extern uint8_t PreviousKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
extern uint8_t CurrentKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
extern void UpdateUsbReports(void);

View File

@@ -4,6 +4,7 @@
#include "i2c.h"
#include "peripherals/reset_button.h"
#include "key_action.h"
#include "usb_protocol_handler.h"
static usb_device_endpoint_struct_t UsbMouseEndpoints[USB_MOUSE_ENDPOINT_COUNT] = {{
USB_MOUSE_ENDPOINT_INDEX | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
@@ -37,12 +38,33 @@ usb_device_class_struct_t UsbMouseClass = {
USB_DEVICE_CONFIGURATION_COUNT,
};
usb_mouse_report_t UsbMouseReport;
usb_mouse_report_t usbMouseReports[2];
usb_mouse_report_t* ActiveUsbMouseReport = usbMouseReports;
bool IsUsbMouseReportSent = false;
usb_mouse_report_t* getInactiveUsbMouseReport(void)
{
return ActiveUsbMouseReport == usbMouseReports ? usbMouseReports+1 : usbMouseReports;
}
void SwitchActiveUsbMouseReport(void)
{
ActiveUsbMouseReport = getInactiveUsbMouseReport();
}
void ResetActiveUsbMouseReport(void)
{
bzero(ActiveUsbMouseReport, USB_MOUSE_REPORT_LENGTH);
}
static volatile usb_status_t usbMouseAction(void)
{
usb_mouse_report_t *mouseReport = getInactiveUsbMouseReport();
*((uint16_t*)(UsbDebugInfo+16)) = mouseReport->x;
*((uint16_t*)(UsbDebugInfo+18)) = mouseReport->y;
IsUsbMouseReportSent = true;
return USB_DeviceHidSend(UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX,
(uint8_t*)&UsbMouseReport, USB_MOUSE_REPORT_LENGTH);
(uint8_t*)mouseReport, USB_MOUSE_REPORT_LENGTH);
}
usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param)

View File

@@ -31,8 +31,9 @@
// Variables:
extern bool IsUsbMouseReportSent;
extern usb_device_class_struct_t UsbMouseClass;
extern usb_mouse_report_t UsbMouseReport;
extern usb_mouse_report_t* ActiveUsbMouseReport;
// Functions:
@@ -40,4 +41,7 @@
usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration);
usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
void ResetActiveUsbMouseReport(void);
void SwitchActiveUsbMouseReport(void);
#endif

View File

@@ -27,10 +27,10 @@ void processMouseAction(key_action_t action)
if (mouseWheelDivisorCounter == MOUSE_WHEEL_DIVISOR) {
mouseWheelDivisorCounter = 0;
if (action.mouse.scrollActions & MouseScroll_Up) {
UsbMouseReport.wheelX = 1;
ActiveUsbMouseReport->wheelX = 1;
}
if (action.mouse.scrollActions & MouseScroll_Down) {
UsbMouseReport.wheelX = -1;
ActiveUsbMouseReport->wheelX = -1;
}
}
}
@@ -54,20 +54,20 @@ void processMouseAction(key_action_t action)
}
} else if (action.mouse.moveActions) {
if (action.mouse.moveActions & MouseMove_Left) {
UsbMouseReport.x = -mouseSpeed;
ActiveUsbMouseReport->x = -mouseSpeed;
}
if (action.mouse.moveActions & MouseMove_Right) {
UsbMouseReport.x = mouseSpeed;
ActiveUsbMouseReport->x = mouseSpeed;
}
if (action.mouse.moveActions & MouseMove_Up) {
UsbMouseReport.y = -mouseSpeed;
ActiveUsbMouseReport->y = -mouseSpeed;
}
if (action.mouse.moveActions & MouseMove_Down) {
UsbMouseReport.y = mouseSpeed;
ActiveUsbMouseReport->y = mouseSpeed;
}
}
UsbMouseReport.buttons |= action.mouse.buttonActions;
ActiveUsbMouseReport->buttons |= action.mouse.buttonActions;
wasPreviousMouseActionWheelAction = isWheelAction;
}
@@ -90,8 +90,6 @@ uint8_t getActiveLayer(void)
void UpdateActiveUsbReports(void)
{
bzero(&UsbMouseReport, sizeof(usb_mouse_report_t));
uint8_t basicScancodeIndex = 0;
uint8_t mediaScancodeIndex = 0;
uint8_t systemScancodeIndex = 0;
@@ -101,7 +99,7 @@ void UpdateActiveUsbReports(void)
if (MacroPlaying) {
Macros_ContinueMacro();
memcpy(&UsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport);
memcpy(&ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport);
memcpy(&ActiveUsbBasicKeyboardReport, &MacroBasicKeyboardReport, sizeof MacroBasicKeyboardReport);
memcpy(&ActiveUsbMediaKeyboardReport, &MacroMediaKeyboardReport, sizeof MacroMediaKeyboardReport);
memcpy(&ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport);

View File

@@ -34,6 +34,27 @@ void KeyMatrix_Scan(key_matrix_t *keyMatrix)
}
GPIO_WritePinOutput(rowGpio, rowPin, 0);
for (volatile uint32_t i=0; i<100; i++); // Wait for the new port state to settle. This avoid bogus key state detection.
for (volatile uint32_t i=0; i<100; i++); // Wait for the new port state to settle. This avoids bogus key state detection.
}
}
void KeyMatrix_ScanRow(key_matrix_t *keyMatrix)
{
uint8_t *keyState = keyMatrix->keyStates + keyMatrix->currentRowNum * keyMatrix->colNum;
key_matrix_pin_t *row = keyMatrix->rows + keyMatrix->currentRowNum;
GPIO_Type *rowGpio = row->gpio;
uint32_t rowPin = row->pin;
GPIO_WritePinOutput(rowGpio, rowPin, 1);
key_matrix_pin_t *colEnd = keyMatrix->cols + keyMatrix->colNum;
for (key_matrix_pin_t *col = keyMatrix->cols; col<colEnd; col++) {
*(keyState++) = GPIO_ReadPinInput(col->gpio, col->pin);
}
GPIO_WritePinOutput(rowGpio, rowPin, 0);
if (++keyMatrix->currentRowNum >= keyMatrix->rowNum) {
keyMatrix->currentRowNum = 0;
}
}

View File

@@ -22,6 +22,7 @@
typedef struct {
uint8_t colNum;
uint8_t rowNum;
uint8_t currentRowNum;
key_matrix_pin_t *cols;
key_matrix_pin_t *rows;
uint8_t keyStates[MAX_KEYS_IN_MATRIX];
@@ -31,5 +32,6 @@
void KeyMatrix_Init(key_matrix_t *keyMatrix);
void KeyMatrix_Scan(key_matrix_t *keyMatrix);
void KeyMatrix_ScanRow(key_matrix_t *keyMatrix);
#endif