Compare commits
2 Commits
efe00d028f
...
f9cc1a72a6
Author | SHA1 | Date | |
---|---|---|---|
f9cc1a72a6 | |||
c8351f0124 |
@ -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,15 +7,12 @@
|
|||||||
#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(15:8) + INT_CFG(7:0) reg
|
||||||
#define EEPROM_VAR_KBD (2) // 16b: DEB + FRQ regs
|
#define EEPROM_VAR_KBD (2) // 32b: DEB(15:0) + 0x00 + FRQ(7:0) regs
|
||||||
#define EEPROM_VAR_BCKL (3) // 16b: LCD + KBD backlight step indice
|
#define EEPROM_VAR_BCKL (3) // 16b: LCD(15:8) + KBD(7:0) backlight step indice
|
||||||
|
|
||||||
//-------------------------------------------library configuration-------------------------------------------
|
//-------------------------------------------library configuration-------------------------------------------
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -83,6 +83,8 @@ void keyboard_set_key_callback(key_callback callback);
|
|||||||
void keyboard_set_lock_callback(lock_callback callback);
|
void keyboard_set_lock_callback(lock_callback callback);
|
||||||
uint8_t keyboard_get_capslock(void);
|
uint8_t keyboard_get_capslock(void);
|
||||||
uint8_t keyboard_get_numlock(void);
|
uint8_t keyboard_get_numlock(void);
|
||||||
|
uint16_t keyboard_get_hold_period(void);
|
||||||
|
void keyboard_set_hold_period(uint16_t);
|
||||||
void keyboard_process(void);
|
void keyboard_process(void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 (time in ms)
|
||||||
|
REG_ID_FRQ = 0x08, //!< poll freq cfg (time in ms)
|
||||||
|
|
||||||
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
|
||||||
|
@ -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;
|
||||||
|
@ -109,6 +109,7 @@ static uint8_t capslock_changed = 0;
|
|||||||
static uint8_t capslock = 0;
|
static uint8_t capslock = 0;
|
||||||
static uint8_t numlock_changed = 0;
|
static uint8_t numlock_changed = 0;
|
||||||
static uint8_t numlock = 0;
|
static uint8_t numlock = 0;
|
||||||
|
static uint16_t hold_period = KEY_HOLD_TIME;
|
||||||
|
|
||||||
uint8_t io_matrix[9] = {0}; //for IO matrix,last byte is the restore key(c64 only)
|
uint8_t io_matrix[9] = {0}; //for IO matrix,last byte is the restore key(c64 only)
|
||||||
uint8_t js_bits = 0xFF; // c64 joystick bits
|
uint8_t js_bits = 0xFF; // c64 joystick bits
|
||||||
@ -130,6 +131,14 @@ inline uint8_t keyboard_get_numlock(void) {
|
|||||||
return numlock & 0x1;
|
return numlock & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint16_t keyboard_get_hold_period(void) {
|
||||||
|
return hold_period;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void keyboard_set_hold_period(uint16_t value) {
|
||||||
|
hold_period = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void transition_to(struct list_item * const p_item, const enum key_state next_state) {
|
static void transition_to(struct list_item * const p_item, const enum key_state next_state) {
|
||||||
uint8_t output = 1;
|
uint8_t output = 1;
|
||||||
const struct entry * const p_entry = p_item->p_entry;
|
const struct entry * const p_entry = p_item->p_entry;
|
||||||
@ -272,7 +281,7 @@ static void next_item_state(struct list_item* const p_item, const uint8_t presse
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_STATE_PRESSED:
|
case KEY_STATE_PRESSED:
|
||||||
if (uptime_ms() > p_item->hold_start_time + KEY_HOLD_TIME) {
|
if (uptime_ms() > p_item->hold_start_time + hold_period) {
|
||||||
transition_to(p_item, KEY_STATE_HOLD);
|
transition_to(p_item, KEY_STATE_HOLD);
|
||||||
p_item->last_repeat_time = uptime_ms();
|
p_item->last_repeat_time = uptime_ms();
|
||||||
} else if (!pressed)
|
} else if (!pressed)
|
||||||
@ -283,7 +292,7 @@ static void next_item_state(struct list_item* const p_item, const uint8_t presse
|
|||||||
if (!pressed)
|
if (!pressed)
|
||||||
transition_to(p_item, KEY_STATE_RELEASED);
|
transition_to(p_item, KEY_STATE_RELEASED);
|
||||||
else {
|
else {
|
||||||
if (uptime_ms() > p_item->hold_start_time + KEY_HOLD_TIME) {
|
if (uptime_ms() > p_item->hold_start_time + hold_period) {
|
||||||
if(uptime_ms() > p_item->last_repeat_time + KEY_REPEAT_TIME) {
|
if(uptime_ms() > p_item->last_repeat_time + KEY_REPEAT_TIME) {
|
||||||
transition_to(p_item, KEY_STATE_HOLD);
|
transition_to(p_item, KEY_STATE_HOLD);
|
||||||
p_item->last_repeat_time = uptime_ms();
|
p_item->last_repeat_time = uptime_ms();
|
||||||
@ -305,7 +314,7 @@ static void next_item_state(struct list_item* const p_item, const uint8_t presse
|
|||||||
void keyboard_process(void) {
|
void keyboard_process(void) {
|
||||||
js_bits = 0xFF;
|
js_bits = 0xFF;
|
||||||
|
|
||||||
if (uptime_ms() <= (last_process_time + KEY_POLL_TIME))
|
if (uptime_ms() <= (last_process_time + reg_get_value(REG_ID_FRQ)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Scan for columns
|
// Scan for columns
|
||||||
|
@ -26,8 +26,10 @@
|
|||||||
// Private define ------------------------------------------------------------
|
// Private define ------------------------------------------------------------
|
||||||
//#define DEFAULT_LCD_BL (205) // ~40% PWM@7.81kHz (9 bits resolution)
|
//#define DEFAULT_LCD_BL (205) // ~40% PWM@7.81kHz (9 bits resolution)
|
||||||
//#define DEFAULT_KBD_BL (20) // ~4% PWM@7.81kHz (9 bits resolution)
|
//#define DEFAULT_KBD_BL (20) // ~4% PWM@7.81kHz (9 bits resolution)
|
||||||
#define DEFAULT_LCD_BL (3) //step-4 (~50%)
|
#define DEFAULT_LCD_BL (3) //step-4 (~50%)
|
||||||
#define DEFAULT_KBD_BL (0) //step-1 (0%)
|
#define DEFAULT_KBD_BL (0) //step-1 (0%)
|
||||||
|
#define DEFAULT_KBD_FREQ (KEY_POLL_TIME)
|
||||||
|
#define DEFAULT_KBD_DEB (KEY_HOLD_TIME)
|
||||||
|
|
||||||
#define I2CS_REARM_TIMEOUT 500
|
#define I2CS_REARM_TIMEOUT 500
|
||||||
#define I2CS_W_BUFF_LEN 31+1 // The last one must be only a 0 value, TODO: another cleaner way?
|
#define I2CS_W_BUFF_LEN 31+1 // The last one must be only a 0 value, TODO: another cleaner way?
|
||||||
@ -68,7 +70,7 @@ volatile uint32_t systicks_counter = 0; // 1 MHz systick counter - TODO: implem
|
|||||||
volatile uint32_t pmu_check_counter = 0;
|
volatile uint32_t pmu_check_counter = 0;
|
||||||
volatile uint32_t i2cs_rearm_counter = 0;
|
volatile uint32_t i2cs_rearm_counter = 0;
|
||||||
|
|
||||||
static uint8_t i2cs_r_buff[2];
|
static uint8_t i2cs_r_buff[5];
|
||||||
static volatile uint8_t i2cs_r_idx = 0;
|
static volatile uint8_t i2cs_r_idx = 0;
|
||||||
static uint8_t i2cs_w_buff[I2CS_W_BUFF_LEN];
|
static uint8_t i2cs_w_buff[I2CS_W_BUFF_LEN];
|
||||||
static volatile uint8_t i2cs_w_idx = 0;
|
static volatile uint8_t i2cs_w_idx = 0;
|
||||||
@ -129,11 +131,33 @@ extern void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirect
|
|||||||
if (is_write)
|
if (is_write)
|
||||||
kbd_backlight_update(i2cs_r_buff[1]);
|
kbd_backlight_update(i2cs_r_buff[1]);
|
||||||
i2cs_w_buff[1] = reg_get_value(REG_ID_BK2);
|
i2cs_w_buff[1] = reg_get_value(REG_ID_BK2);
|
||||||
|
} else if (reg == REG_ID_CFG) {
|
||||||
|
if (is_write)
|
||||||
|
reg_set_value(REG_ID_CFG, i2cs_r_buff[1]);
|
||||||
|
i2cs_w_buff[1] = reg_get_value(REG_ID_CFG);
|
||||||
|
} else if (reg == REG_ID_INT_CFG) {
|
||||||
|
if (is_write)
|
||||||
|
reg_set_value(REG_ID_INT_CFG, i2cs_r_buff[1]);
|
||||||
|
i2cs_w_buff[1] = reg_get_value(REG_ID_INT_CFG);
|
||||||
|
} else if (reg == REG_ID_DEB) {
|
||||||
|
if (is_write) {
|
||||||
|
keyboard_set_hold_period(*((uint16_t*)&i2cs_r_buff[1]));
|
||||||
|
reg_set_value(REG_ID_DEB, 0); // Trig async flag for EEPROM saving
|
||||||
|
}
|
||||||
|
*((uint16_t*)&i2cs_w_buff[1]) = keyboard_get_hold_period();
|
||||||
|
i2cs_w_len = 3;
|
||||||
|
} else if (reg == REG_ID_FRQ) {
|
||||||
|
if (is_write)
|
||||||
|
reg_set_value(REG_ID_FRQ, i2cs_r_buff[1]);
|
||||||
|
i2cs_w_buff[1] = reg_get_value(REG_ID_FRQ);
|
||||||
} else if (reg == REG_ID_FIF) {
|
} else if (reg == REG_ID_FIF) {
|
||||||
struct fifo_item item = {0};
|
struct fifo_item item = {0};
|
||||||
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) {
|
||||||
@ -185,14 +209,24 @@ extern void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
|||||||
if (i2cs_state == I2CS_STATE_REG_REQUEST) {
|
if (i2cs_state == I2CS_STATE_REG_REQUEST) {
|
||||||
const uint8_t is_write = (uint8_t)(i2cs_r_buff[0] & (1 << 7));
|
const uint8_t is_write = (uint8_t)(i2cs_r_buff[0] & (1 << 7));
|
||||||
const uint8_t reg = (uint8_t)(i2cs_r_buff[0] & ~(1 << 7));
|
const uint8_t reg = (uint8_t)(i2cs_r_buff[0] & ~(1 << 7));
|
||||||
|
uint8_t bytes_needed = 0;
|
||||||
|
|
||||||
// We wait an another byte for these registers
|
// Check for another mandatories bytes depending on register requested
|
||||||
if (reg == REG_ID_BKL ||
|
if (reg == REG_ID_BKL ||
|
||||||
reg == REG_ID_BK2) {
|
reg == REG_ID_BK2 ||
|
||||||
if (is_write) {
|
reg == REG_ID_CFG ||
|
||||||
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2cs_r_buff + i2cs_r_idx, 1, I2C_NEXT_FRAME); // This write the second received byte to i2cs_r_buff[1]
|
reg == REG_ID_INT_CFG ||
|
||||||
}
|
reg == REG_ID_FRQ) {
|
||||||
|
if (is_write)
|
||||||
|
bytes_needed = 1;
|
||||||
|
|
||||||
|
} else if (reg == REG_ID_DEB) {
|
||||||
|
if (is_write)
|
||||||
|
bytes_needed = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes_needed > 0)
|
||||||
|
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2cs_r_buff + i2cs_r_idx, bytes_needed, I2C_NEXT_FRAME); // This write the second or more received byte to i2cs_r_buff[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,8 +292,8 @@ int main(void) {
|
|||||||
EEPROM_ReadVariable(EEPROM_VAR_ID, (EEPROM_Value*)&result);
|
EEPROM_ReadVariable(EEPROM_VAR_ID, (EEPROM_Value*)&result);
|
||||||
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)(uint32_t)((DEFAULT_KBD_DEB << 16) | DEFAULT_KBD_FREQ), EEPROM_SIZE32);
|
||||||
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 +438,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,10 +93,10 @@ 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)(uint32_t)((keyboard_get_hold_period() << 16) | regs[REG_ID_FRQ]), EEPROM_SIZE32);
|
||||||
|
|
||||||
if (regs_unsync[REG_ID_BKL] == 1 || regs_unsync[REG_ID_BK2] == 1)
|
if (regs_unsync[REG_ID_BKL] == 1 || regs_unsync[REG_ID_BK2] == 1)
|
||||||
result |= EEPROM_WriteVariable(EEPROM_VAR_BCKL, (EEPROM_Value)(uint16_t)((regs[REG_ID_BKL] << 8) | regs[REG_ID_BK2]), EEPROM_SIZE16);
|
result |= EEPROM_WriteVariable(EEPROM_VAR_BCKL, (EEPROM_Value)(uint16_t)((regs[REG_ID_BKL] << 8) | regs[REG_ID_BK2]), EEPROM_SIZE16);
|
||||||
|
6
Makefile
6
Makefile
@ -20,6 +20,8 @@ TARGET = picocalc_BIOS_jcs
|
|||||||
DEBUG = 0
|
DEBUG = 0
|
||||||
# optimization
|
# optimization
|
||||||
OPT = -O3
|
OPT = -O3
|
||||||
|
# use old I2C registers structure
|
||||||
|
I2C_REGS_COMPAT = 0
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
@ -122,6 +124,10 @@ ifeq ($(DEBUG), 1)
|
|||||||
C_DEFS += -DDEBUG
|
C_DEFS += -DDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(I2C_REGS_COMPAT), 1)
|
||||||
|
C_DEFS += -DI2C_REGS_COMPAT
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# AS includes
|
# AS includes
|
||||||
AS_INCLUDES =
|
AS_INCLUDES =
|
||||||
|
17
README.md
17
README.md
@ -7,15 +7,28 @@ PicoCalc STM32F103R8T6 firmware.
|
|||||||
The main differences with the original firmware are the followings:
|
The main differences with the original firmware are the followings:
|
||||||
|
|
||||||
- drastic reduction in the STM32's electricity consumption when running (~3.5 mA),
|
- drastic reduction in the STM32's electricity consumption when running (~3.5 mA),
|
||||||
- clean up (in progress) to reduce binary size (~25 KB) and allow more features to be implemented,
|
- clean up (by removing stm32duino dependencies, use STM32HAL instead, maybe I'll switch to libopencm3 someday...) to reduce binary size (~25 KB) and allow more features to be implemented,
|
||||||
- removed stm32duino dependencies (use STM32HAL instead, maybe I'll switch to libopencm3 someday...),
|
|
||||||
- added configuration saving solution (using internal flash, including backlight option),
|
- added configuration saving solution (using internal flash, including backlight option),
|
||||||
|
- new I2C registers and structure (keeping compatible access to REG_ID_TYP and REG_ID_VER registers to check how to handle comm from pico board side),
|
||||||
|
- interrupt event output to pico board can be configured during runtime (for keyboard event or RTC alarm),
|
||||||
- rewriten or added some debug UART interface message,
|
- rewriten or added some debug UART interface message,
|
||||||
|
- internal RTC access through dedicated I2C registers (WIP),
|
||||||
- lighten AXP2101 PMIC driver.
|
- lighten AXP2101 PMIC driver.
|
||||||
|
|
||||||
## Compile
|
## Compile
|
||||||
This source code can be compiled using ARM gcc toolchain (using v13) in path and using make program.
|
This source code can be compiled using ARM gcc toolchain (using v13) in path and using make program.
|
||||||
|
|
||||||
|
CAUTION: By default, I2C registers use a new, exploded structure that is more flexible!
|
||||||
|
But this makes them incompatible with official firmware. (More details to come about I2C registers structure in the wiki...)
|
||||||
|
|
||||||
|
If you plan using pico official firmware (PicoMite, etc.), you should set I2C_REGS_COMPAT = 1 in the Makefile.
|
||||||
|
|
||||||
|
## Important notes
|
||||||
|
The current implementation of this firmware is subject to change until the v1 release.
|
||||||
|
|
||||||
|
The permanent settings (EEPROM) save can be broken between 0.x version, it is recommanded to make a full flash erase before updating, as
|
||||||
|
EEPROM configuration survives update.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
- STM32-HAL: [link](https://github.com/STMicroelectronics/stm32f1xx-hal-driver)
|
- STM32-HAL: [link](https://github.com/STMicroelectronics/stm32f1xx-hal-driver)
|
||||||
- STM32-CMSIS: [link](https://github.com/STMicroelectronics/cmsis-device-f1)
|
- STM32-CMSIS: [link](https://github.com/STMicroelectronics/cmsis-device-f1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user