This commit is contained in:
Vitalii 2025-05-14 13:49:50 +03:00
parent b07c0607d3
commit 81bf2711cc
Signed by: SymbX
GPG Key ID: FF51F4E4BCE459EE
1 changed files with 46 additions and 18 deletions

View File

@ -4,39 +4,51 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
// Use watchdog
#define WATCHDOG #define WATCHDOG
// UART buffer size
#define BUFFER_LEN 48 #define BUFFER_LEN 48
// LED pin info
#define LED_PIN_DIR PORT_C.DDR.Pin3 #define LED_PIN_DIR PORT_C.DDR.Pin3
#define LED_PIN_CR1 PORT_C.CR1.Pin3 #define LED_PIN_CR1 PORT_C.CR1.Pin3
#define LED_PIN_CR2 PORT_C.CR2.Pin3 #define LED_PIN_CR2 PORT_C.CR2.Pin3
#define LED_PIN_OUT PORT_C.ODR.Pin3 #define LED_PIN_OUT PORT_C.ODR.Pin3
// UART RX pin info
#define RX_PIN_DIR PORT_D.DDR.Pin6 #define RX_PIN_DIR PORT_D.DDR.Pin6
#define RX_PIN_CR1 PORT_D.CR1.Pin6 #define RX_PIN_CR1 PORT_D.CR1.Pin6
#define RX_PIN_CR2 PORT_D.CR2.Pin6 #define RX_PIN_CR2 PORT_D.CR2.Pin6
#define RX_PIN_OUT PORT_D.ODR.Pin6 #define RX_PIN_OUT PORT_D.ODR.Pin6
// UART TX pin info
#define TX_PIN_DIR PORT_D.DDR.Pin5 #define TX_PIN_DIR PORT_D.DDR.Pin5
#define TX_PIN_CR1 PORT_D.CR1.Pin5 #define TX_PIN_CR1 PORT_D.CR1.Pin5
#define TX_PIN_CR2 PORT_D.CR2.Pin5 #define TX_PIN_CR2 PORT_D.CR2.Pin5
#define TX_PIN_OUT PORT_D.ODR.Pin5 #define TX_PIN_OUT PORT_D.ODR.Pin5
// Time defines
#define SHORT_PRESS_MS 25 #define SHORT_PRESS_MS 25
#define LONG_PRESS_MS 1000 #define LONG_PRESS_MS 1000
#define LED_FADE_TIME 888
// Countdown timestamp (2^15 max, sign used to notify "unitialized") // Countdown timestamp (2^15 max, sign used to notify "unitialized")
volatile i16 countdown_tick = 0; volatile i16 countdown_tick = 0;
// Light timer
// volatile u08 exec = 0;
volatile i16 timer = 0; volatile i16 timer = 0;
// volatile u08 exec = 0;
volatile u08 cmd[BUFFER_LEN]; volatile u08 cmd[BUFFER_LEN];
volatile u08 cmdPos = 0; volatile u08 cmdPos = 0;
volatile u08 cmdLen = 0; volatile u08 cmdLen = 0;
volatile u08 state = 0; volatile u08 state = 0;
u08 led_state = 0;
/**
* Hang processor with big delay and hope for watchdog to kick-in or directly
* start watchdog restart by setting counter to 0.
*/
void reboot(void) { void reboot(void) {
#ifdef WATCHDOG #ifdef WATCHDOG
IWATCHDOG.Key = IndependWatchdogReset; IWATCHDOG.Key = IndependWatchdogReset;
@ -47,6 +59,9 @@ void reboot(void) {
WWDG.Control.Counter = 0; WWDG.Control.Counter = 0;
} }
/**
* Start feeding cmd into UART (will process with interrupts)
*/
void start_cmd(u08 len) { void start_cmd(u08 len) {
cmdPos = 0; cmdPos = 0;
cmdLen = len; cmdLen = len;
@ -84,6 +99,7 @@ i16 elapsed(void) {
} }
u16 next = (TIM1.CounterH << 8) | TIM1.CounterL; u16 next = (TIM1.CounterH << 8) | TIM1.CounterL;
if (next < countdown_tick) { if (next < countdown_tick) {
// Handle case if timer overflowed
return (next + 2500) - countdown_tick; return (next + 2500) - countdown_tick;
} else { } else {
return next - countdown_tick; return next - countdown_tick;
@ -111,14 +127,16 @@ void initialize_state(void) {
state++; state++;
} }
#define LED_DELAY 888 /**
u08 led_state = 0; * Fade in LED for ticks defined in LED_FADE_TIME
* Note: if already turned on - do nothing
*/
void turn_on(void) { void turn_on(void) {
if (led_state == 1) { if (led_state == 1) {
return; return;
} }
led_state = 1; led_state = 1;
u16 delay = LED_DELAY; u16 delay = LED_FADE_TIME;
while (delay > 1) { while (delay > 1) {
LED_PIN_OUT ^= 1; LED_PIN_OUT ^= 1;
delay_tick(delay); delay_tick(delay);
@ -127,13 +145,17 @@ void turn_on(void) {
LED_PIN_OUT = 1; LED_PIN_OUT = 1;
} }
/**
* Fade out LED for ticks defined in LED_FADE_TIME
* Note: if already turned of - do nothing
*/
void turn_off(void) { void turn_off(void) {
if (led_state == 0) { if (led_state == 0) {
return; return;
} }
led_state = 0; led_state = 0;
u16 delay = 1; u16 delay = 1;
while (delay < LED_DELAY) { while (delay < LED_FADE_TIME) {
LED_PIN_OUT ^= 1; LED_PIN_OUT ^= 1;
delay_tick(delay); delay_tick(delay);
delay++; delay++;
@ -141,18 +163,30 @@ void turn_off(void) {
LED_PIN_OUT = 0; LED_PIN_OUT = 0;
} }
/**
* Tick event handler
*/
void tick_250ms(void) { void tick_250ms(void) {
// Go trough all initialization states
if (state < 2) {
initialize_state();
} else {
// and skip other tasks if not finished
return;
}
// Decrease light timer
if (timer > 0) { if (timer > 0) {
timer--; timer--;
} }
// If we still have time
// note: timer can be below zero to work without timer
if (timer != 0) { if (timer != 0) {
// Keep light on (will do nothing if already enabled)
turn_on(); turn_on();
} else { } else {
// Turn off otherwise
turn_off(); turn_off();
} }
if (state < 2) {
initialize_state();
}
} }
interrupt(IRQ_UART1_RX_F, uart_recv) { interrupt(IRQ_UART1_RX_F, uart_recv) {
@ -228,6 +262,7 @@ void main(void) {
CLK.SwitchControl.SwitchStartStop = 1; CLK.SwitchControl.SwitchStartStop = 1;
CLK.Divider.Prescaler = 0x00; CLK.Divider.Prescaler = 0x00;
CLK.Divider.HighSpeedPrescaler = 0x00; CLK.Divider.HighSpeedPrescaler = 0x00;
// Disable unused peripherals
CLK.Peripheral1.I2C= 0; CLK.Peripheral1.I2C= 0;
CLK.Peripheral1.SPI = 0; CLK.Peripheral1.SPI = 0;
CLK.Peripheral1.Timer2 = 0; CLK.Peripheral1.Timer2 = 0;
@ -291,13 +326,6 @@ void main(void) {
// Start interrupts // Start interrupts
rim(); rim();
// Fast blink on start
/* for (u08 j = 0; j < 10; j++) {
LED_PIN_OUT ^= 1;
delay_tick(0xffff);
IWATCHDOG.Key = IndependWatchdogReset;
} */
// Just for test // Just for test
CFG_GCR |= 0x02; // Set AL for disable main(); CFG_GCR |= 0x02; // Set AL for disable main();
wfi(); wfi();