New I2C registers IRQ mechanism

Compatibility mode added
This commit is contained in:
JackCarterSmith 2025-05-08 17:54:11 +02:00
parent 7e58a74f5a
commit c8351f0124
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
6 changed files with 69 additions and 32 deletions

View File

@ -1,3 +1,4 @@
#include "stm32f1xx_hal.h"
//EEPROM emulation library for STM32F1XX with HAL-Driver //EEPROM emulation library for STM32F1XX with HAL-Driver
//V2.0 //V2.0
@ -6,13 +7,10 @@
#ifndef __EEPROM_H #ifndef __EEPROM_H
#define __EEPROM_H #define __EEPROM_H
//includes
#include "stm32f1xx_hal.h"
//---------------------------------------------Datas registration-------------------------------------------- //---------------------------------------------Datas registration--------------------------------------------
#define EEPROM_VAR_ID (0) // 16b: Init ID: 0xCA1C #define EEPROM_VAR_ID (0) // 16b: Init ID: 0xCA1C
#define EEPROM_VAR_CFG (1) // 16b: 0x00 + CFG reg #define EEPROM_VAR_CFG (1) // 16b: CFG + INT_CFG reg
#define EEPROM_VAR_KBD (2) // 16b: DEB + FRQ regs #define EEPROM_VAR_KBD (2) // 16b: DEB + FRQ regs
#define EEPROM_VAR_BCKL (3) // 16b: LCD + KBD backlight step indice #define EEPROM_VAR_BCKL (3) // 16b: LCD + KBD backlight step indice

View File

@ -103,10 +103,15 @@ extern "C" {
#define PICO_EN_GPIO_Port GPIOA #define PICO_EN_GPIO_Port GPIOA
#define SP_AMP_EN_Pin LL_GPIO_PIN_14 #define SP_AMP_EN_Pin LL_GPIO_PIN_14
#define SP_AMP_EN_GPIO_Port GPIOA #define SP_AMP_EN_GPIO_Port GPIOA
#ifdef UART_PICO_INTERFACE
#define PICO_UART_TX_Pin LL_GPIO_PIN_10 #define PICO_UART_TX_Pin LL_GPIO_PIN_10
#define PICO_UART_TX_GPIO_Port GPIOC #define PICO_UART_TX_GPIO_Port GPIOC
#define PICO_UART_RX_Pin LL_GPIO_PIN_11 #define PICO_UART_RX_Pin LL_GPIO_PIN_11
#define PICO_UART_RX_GPIO_Port GPIOC #define PICO_UART_RX_GPIO_Port GPIOC
#else
#define PICO_IRQ_Pin LL_GPIO_PIN_10
#define PICO_IRQ_GPIO_Port GPIOC
#endif
#define HP_DET_Pin LL_GPIO_PIN_12 #define HP_DET_Pin LL_GPIO_PIN_12
#define HP_DET_GPIO_Port GPIOC #define HP_DET_GPIO_Port GPIOC
#define KEY_4_Pin LL_GPIO_PIN_3 #define KEY_4_Pin LL_GPIO_PIN_3

View File

@ -4,9 +4,10 @@
#ifndef REGS_H_ #ifndef REGS_H_
#define REGS_H_ #define REGS_H_
enum reg_id enum reg_id {
{ REG_ID_TYP = 0x00, //!< firmware type (0=official, others=custom)
REG_ID_VER = 0x01, // fw version (7:4=Major, 3:0=Minor) REG_ID_VER = 0x01, //!< fw version (7:4=Major, 3:0=Minor)
#ifdef I2C_REGS_COMPAT
REG_ID_CFG = 0x02, // config REG_ID_CFG = 0x02, // config
REG_ID_INT = 0x03, // interrupt status REG_ID_INT = 0x03, // interrupt status
REG_ID_KEY = 0x04, // key status REG_ID_KEY = 0x04, // key status
@ -21,18 +22,31 @@ enum reg_id
REG_ID_C64_JS = 0x0D, // joystick io bits REG_ID_C64_JS = 0x0D, // joystick io bits
REG_ID_RST_PICO = 0x0E, // Pico reset REG_ID_RST_PICO = 0x0E, // Pico reset
REG_ID_SHTDW = 0x0F, // self-shutdown REG_ID_SHTDW = 0x0F, // self-shutdown
REG_ID_INT_CFG = 0x10, // IRQ config
#else
REG_ID_CFG = 0x02, //!< config
REG_ID_INT_CFG = 0x03, //!< IRQ config
REG_ID_INT = 0x04, //!< interrupt status
REG_ID_BKL = 0x05, //!< backlight steps (0-9)
REG_ID_BK2 = 0x06, //!< keyboard backlight (0-9)
REG_ID_DEB = 0x07, //!< debounce cfg
REG_ID_FRQ = 0x08, //!< poll freq cfg
REG_ID_TYP = 0xFF, // firmware type (0=official, others=custom) REG_ID_KEY = 0x10, //!< key status
REG_ID_FIF = 0x11, //!< fifo
REG_ID_C64_MTX = 0x12, //!< read c64 matrix
REG_ID_C64_JS = 0x13, //!< joystick io bits
REG_ID_RST = 0x20, //!< STM32 full reset
REG_ID_RST_PICO = 0x21, //!< Pico reset
REG_ID_SHTDW = 0x22, //!< self-shutdown
REG_ID_BAT = 0x30, //!< battery
#endif
REG_ID_LAST, REG_ID_LAST,
}; };
#define CFG_OVERFLOW_ON (1 << 0) //When a FIFO overflow happens, should the new entry still be pushed, overwriting the oldest one. If 0 then new entry is lost. #define CFG_OVERFLOW_ON (1 << 0) //When a FIFO overflow happens, should the new entry still be pushed, overwriting the oldest one. If 0 then new entry is lost.
#define CFG_OVERFLOW_INT (1 << 1) //Should an interrupt be generated when a FIFO overflow happens
#define CFG_CAPSLOCK_INT (1 << 2) //Should an interrupt be generated when Caps Lock is toggled.
#define CFG_NUMLOCK_INT (1 << 3) //Should an interrupt be generated when Num Lock is toggled.
#define CFG_KEY_INT (1 << 4)
#define CFG_PANIC_INT (1 << 5)
#define CFG_REPORT_MODS (1 << 6) // Should Alt, Sym and Shifts be reported as well #define CFG_REPORT_MODS (1 << 6) // Should Alt, Sym and Shifts be reported as well
#define CFG_USE_MODS (1 << 7) // Should Alt, Sym and Shifts modify the keys reported #define CFG_USE_MODS (1 << 7) // Should Alt, Sym and Shifts modify the keys reported
// CFG_STICKY_MODS // Pressing and releasing a mod affects next key pressed // CFG_STICKY_MODS // Pressing and releasing a mod affects next key pressed

View File

@ -367,6 +367,14 @@ static void MX_GPIO_Init(void) {
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct); LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
#ifndef UART_PICO_INTERFACE
GPIO_InitStruct.Pin = PICO_IRQ_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
#endif
/**/ /**/
GPIO_InitStruct.Pin = ROW_1_Pin|ROW_2_Pin|ROW_3_Pin|ROW_4_Pin GPIO_InitStruct.Pin = ROW_1_Pin|ROW_2_Pin|ROW_3_Pin|ROW_4_Pin
|ROW_5_Pin|ROW_6_Pin|ROW_7_Pin|ROW_8_Pin; |ROW_5_Pin|ROW_6_Pin|ROW_7_Pin|ROW_8_Pin;

View File

@ -134,6 +134,9 @@ extern void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirect
fifo_dequeue(&item); fifo_dequeue(&item);
i2cs_w_buff[0] = item.state; i2cs_w_buff[0] = item.state;
i2cs_w_buff[1] = item.key; i2cs_w_buff[1] = item.key;
} else if (reg == REG_ID_INT) {
i2cs_w_buff[1] = reg_get_value(REG_ID_INT);
LL_GPIO_SetOutputPin(PICO_IRQ_GPIO_Port, PICO_IRQ_Pin); // De-assert the IRQ signal
} else if (reg == REG_ID_VER) { } else if (reg == REG_ID_VER) {
i2cs_w_buff[1] = reg_get_value(REG_ID_VER); i2cs_w_buff[1] = reg_get_value(REG_ID_VER);
} else if (reg == REG_ID_TYP) { } else if (reg == REG_ID_TYP) {
@ -259,7 +262,7 @@ int main(void) {
if ((uint16_t)result != 0xCA1C) { if ((uint16_t)result != 0xCA1C) {
EEPROM_WriteVariable(EEPROM_VAR_BCKL, (EEPROM_Value)(uint16_t)((DEFAULT_LCD_BL << 8) | DEFAULT_KBD_BL), EEPROM_SIZE16); EEPROM_WriteVariable(EEPROM_VAR_BCKL, (EEPROM_Value)(uint16_t)((DEFAULT_LCD_BL << 8) | DEFAULT_KBD_BL), EEPROM_SIZE16);
EEPROM_WriteVariable(EEPROM_VAR_KBD, (EEPROM_Value)(uint16_t)((10 << 8) | 5), EEPROM_SIZE16); EEPROM_WriteVariable(EEPROM_VAR_KBD, (EEPROM_Value)(uint16_t)((10 << 8) | 5), EEPROM_SIZE16);
EEPROM_WriteVariable(EEPROM_VAR_CFG, (EEPROM_Value)(uint16_t)(CFG_OVERFLOW_INT | CFG_KEY_INT | CFG_USE_MODS | CFG_REPORT_MODS), EEPROM_SIZE16); EEPROM_WriteVariable(EEPROM_VAR_CFG, (EEPROM_Value)(uint16_t)(((CFG_USE_MODS | CFG_REPORT_MODS) << 8) | (INT_OVERFLOW | INT_KEY)), EEPROM_SIZE16);
EEPROM_WriteVariable(EEPROM_VAR_ID, (EEPROM_Value)(uint16_t)0xCA1C, EEPROM_SIZE16); EEPROM_WriteVariable(EEPROM_VAR_ID, (EEPROM_Value)(uint16_t)0xCA1C, EEPROM_SIZE16);
#ifdef DEBUG #ifdef DEBUG
DEBUG_UART_MSG("EEPROM first start!\n\r"); DEBUG_UART_MSG("EEPROM first start!\n\r");
@ -404,54 +407,62 @@ int main(void) {
/* /*
static void lock_cb(uint8_t caps_changed, uint8_t num_changed) { static void lock_cb(uint8_t caps_changed, uint8_t num_changed) {
//uint8_t do_int = 0; uint8_t int_trig = 0;
if (caps_changed && reg_is_bit_set(REG_ID_CFG, CFG_CAPSLOCK_INT)) { if (caps_changed && reg_is_bit_set(REG_ID_CFG, CFG_CAPSLOCK_INT)) {
reg_set_bit(REG_ID_INT, INT_CAPSLOCK); reg_set_bit(REG_ID_INT, INT_CAPSLOCK);
//do_int = 1; int_trig = 1;
} }
if (num_changed && reg_is_bit_set(REG_ID_CFG, CFG_NUMLOCK_INT)) { if (num_changed && reg_is_bit_set(REG_ID_CFG, CFG_NUMLOCK_INT)) {
reg_set_bit(REG_ID_INT, INT_NUMLOCK); reg_set_bit(REG_ID_INT, INT_NUMLOCK);
//do_int = 1; int_trig = 1;
} }
// int_pin can be a LED #ifndef UART_PICO_INTERFACE
if (do_int) { if (int_trig == 1)
port_pin_set_output_level(int_pin, 0); LL_GPIO_ResetOutputPin(PICO_IRQ_GPIO_Port, PICO_IRQ_Pin); // Assert the IRQ signal to the pico
delay_ms(INT_DURATION_MS); #endif
port_pin_set_output_level(int_pin, 1);
}
} }
*/ */
static void key_cb(char key, enum key_state state) { static void key_cb(char key, enum key_state state) {
uint8_t int_trig = 0;
if (keycb_start == 0) { if (keycb_start == 0) {
fifo_flush(); fifo_flush();
return; return;
} }
if (reg_is_bit_set(REG_ID_CFG, CFG_KEY_INT)) { if (reg_is_bit_set(REG_ID_INT_CFG, INT_KEY)) {
reg_set_bit(REG_ID_INT, INT_KEY); reg_set_bit(REG_ID_INT, INT_KEY);
int_trig = 1;
} }
#ifdef DEBUG #ifdef DEBUG
// Serial1.println("key: 0x%02X/%d/%c, state: %d, blk: %d\r\n", key, key, key, state, reg_get_value(REG_ID_BKL)); DEBUG_UART_MSG("key: ");
//HAL_UART_Transmit_IT(&huart1, HP_PLUG_MSG, HP_PLUG_MSG_LEN); DEBUG_UART_MSG2(key, 1, 0);
DEBUG_UART_MSG("\n\r");
DEBUG_UART_MSG("state: ");
DEBUG_UART_MSG2(state, 1, 0);
//DEBUG_UART_MSG(" blk: ");
//DEBUG_UART_MSG2(reg_get_value(REG_ID_BKL), 1, 0);
DEBUG_UART_MSG("\n\r");
#endif #endif
const struct fifo_item item = {key, state}; const struct fifo_item item = {key, state};
if (!fifo_enqueue(item)) { if (!fifo_enqueue(item)) {
if (reg_is_bit_set(REG_ID_CFG, CFG_OVERFLOW_INT)) { if (reg_is_bit_set(REG_ID_INT_CFG, INT_OVERFLOW)) {
reg_set_bit(REG_ID_INT, INT_OVERFLOW); // INT_OVERFLOW The interrupt was generated by FIFO overflow. reg_set_bit(REG_ID_INT, INT_OVERFLOW); // INT_OVERFLOW The interrupt was generated by FIFO overflow.
int_trig = 1;
} }
if (reg_is_bit_set(REG_ID_CFG, CFG_OVERFLOW_ON)) fifo_enqueue_force(item); if (reg_is_bit_set(REG_ID_CFG, CFG_OVERFLOW_ON)) fifo_enqueue_force(item);
} }
#ifdef DEBUG #ifndef UART_PICO_INTERFACE
//Serial1.println(key); if (int_trig == 1)
//HAL_UART_Transmit_IT(&huart1, HP_PLUG_MSG, HP_PLUG_MSG_LEN); LL_GPIO_ResetOutputPin(PICO_IRQ_GPIO_Port, PICO_IRQ_Pin); // Assert the IRQ signal to the pico
#endif #endif
} }

View File

@ -63,7 +63,8 @@ void reg_init(void) {
regs[REG_ID_VER] = (uint8_t)((VERSION_MAJOR << 4) | VERSION_MINOR); // 1.2 => (0x1 << 4) | 0x2 regs[REG_ID_VER] = (uint8_t)((VERSION_MAJOR << 4) | VERSION_MINOR); // 1.2 => (0x1 << 4) | 0x2
EEPROM_ReadVariable(EEPROM_VAR_CFG, (EEPROM_Value*)&buff); EEPROM_ReadVariable(EEPROM_VAR_CFG, (EEPROM_Value*)&buff);
regs[REG_ID_CFG] = (uint8_t)(buff & 0xFF); regs[REG_ID_CFG] = (uint8_t)((buff >> 8) & 0xFF);
regs[REG_ID_INT_CFG] = (uint8_t)(buff & 0xFF);
EEPROM_ReadVariable(EEPROM_VAR_KBD, (EEPROM_Value*)&buff); EEPROM_ReadVariable(EEPROM_VAR_KBD, (EEPROM_Value*)&buff);
regs[REG_ID_DEB] = (uint8_t)((buff >> 8) & 0xFF); regs[REG_ID_DEB] = (uint8_t)((buff >> 8) & 0xFF);
@ -92,7 +93,7 @@ uint32_t reg_check_and_save_eeprom(void) {
if (need_save == 1) { if (need_save == 1) {
if (regs_unsync[REG_ID_CFG] == 1) if (regs_unsync[REG_ID_CFG] == 1)
result |= EEPROM_WriteVariable(EEPROM_VAR_CFG, (EEPROM_Value)(uint16_t)regs[REG_ID_CFG], EEPROM_SIZE16); result |= EEPROM_WriteVariable(EEPROM_VAR_CFG, (EEPROM_Value)(uint16_t)((regs[REG_ID_CFG] << 8) | regs[REG_ID_INT_CFG]), EEPROM_SIZE16);
if (regs_unsync[REG_ID_DEB] == 1 || regs_unsync[REG_ID_FRQ] == 1) if (regs_unsync[REG_ID_DEB] == 1 || regs_unsync[REG_ID_FRQ] == 1)
result |= EEPROM_WriteVariable(EEPROM_VAR_KBD, (EEPROM_Value)(uint16_t)((regs[REG_ID_DEB] << 8) | regs[REG_ID_FRQ]), EEPROM_SIZE16); result |= EEPROM_WriteVariable(EEPROM_VAR_KBD, (EEPROM_Value)(uint16_t)((regs[REG_ID_DEB] << 8) | regs[REG_ID_FRQ]), EEPROM_SIZE16);