initial
This commit is contained in:
+312
@@ -0,0 +1,312 @@
|
||||
#include <type.h>
|
||||
#include <stm_base.h>
|
||||
#include <stm8s103f3.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WATCHDOG
|
||||
|
||||
#define BUFFER_LEN 48
|
||||
|
||||
#define LED_PIN_DIR PORT_C.DDR.Pin3
|
||||
#define LED_PIN_CR1 PORT_C.CR1.Pin3
|
||||
#define LED_PIN_CR2 PORT_C.CR2.Pin3
|
||||
#define LED_PIN_OUT PORT_C.ODR.Pin3
|
||||
|
||||
#define RX_PIN_DIR PORT_D.DDR.Pin6
|
||||
#define RX_PIN_CR1 PORT_D.CR1.Pin6
|
||||
#define RX_PIN_CR2 PORT_D.CR2.Pin6
|
||||
#define RX_PIN_OUT PORT_D.ODR.Pin6
|
||||
|
||||
#define TX_PIN_DIR PORT_D.DDR.Pin5
|
||||
#define TX_PIN_CR1 PORT_D.CR1.Pin5
|
||||
#define TX_PIN_CR2 PORT_D.CR2.Pin5
|
||||
#define TX_PIN_OUT PORT_D.ODR.Pin5
|
||||
|
||||
#define SHORT_PRESS_MS 25
|
||||
#define LONG_PRESS_MS 1000
|
||||
|
||||
// Countdown timestamp (2^15 max, sign used to notify "unitialized")
|
||||
volatile i16 countdown_tick = 0;
|
||||
|
||||
// volatile u08 exec = 0;
|
||||
volatile i16 timer = 0;
|
||||
|
||||
volatile u08 cmd[BUFFER_LEN];
|
||||
volatile u08 cmdPos = 0;
|
||||
volatile u08 cmdLen = 0;
|
||||
volatile u08 state = 0;
|
||||
|
||||
void reboot(void) {
|
||||
#ifdef WATCHDOG
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#else
|
||||
delay_tick(0xffff);
|
||||
#endif
|
||||
WWDG.Control.Activate = 1;
|
||||
WWDG.Control.Counter = 0;
|
||||
}
|
||||
|
||||
void start_cmd(u08 len) {
|
||||
cmdPos = 0;
|
||||
cmdLen = len;
|
||||
UART1.CR2 |= UART_CR2_TXE_IVT;
|
||||
UART1.Data = cmd[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark current time for further comparison
|
||||
*/
|
||||
inline void start_countdown(void) {
|
||||
countdown_tick = (TIM1.CounterH << 8) | TIM1.CounterL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark countdown as unitialized
|
||||
*/
|
||||
inline void stop_countdown(void) {
|
||||
countdown_tick = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if countdown is active
|
||||
*/
|
||||
inline bool is_countdown_active(void) {
|
||||
return countdown_tick >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time elapsed from countdown start in ms
|
||||
*/
|
||||
i16 elapsed(void) {
|
||||
if (!is_countdown_active()) {
|
||||
return -1;
|
||||
}
|
||||
u16 next = (TIM1.CounterH << 8) | TIM1.CounterL;
|
||||
if (next < countdown_tick) {
|
||||
return (next + 2500) - countdown_tick;
|
||||
} else {
|
||||
return next - countdown_tick;
|
||||
}
|
||||
}
|
||||
|
||||
void send_some_command(void) {
|
||||
cmd[0] = 'C';
|
||||
cmd[1] = 'M';
|
||||
cmd[2] = 'D';
|
||||
start_cmd(3);
|
||||
}
|
||||
|
||||
void initialize_state(void) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
send_some_command();
|
||||
// initialization step 0
|
||||
break;
|
||||
case 1:
|
||||
send_some_command();
|
||||
// initialization step 1
|
||||
break;
|
||||
}
|
||||
state++;
|
||||
}
|
||||
|
||||
#define LED_DELAY 888
|
||||
u08 led_state = 0;
|
||||
void turn_on(void) {
|
||||
if (led_state == 1) {
|
||||
return;
|
||||
}
|
||||
led_state = 1;
|
||||
u16 delay = LED_DELAY;
|
||||
while (delay > 1) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(delay);
|
||||
delay--;
|
||||
}
|
||||
LED_PIN_OUT = 1;
|
||||
}
|
||||
|
||||
void turn_off(void) {
|
||||
if (led_state == 0) {
|
||||
return;
|
||||
}
|
||||
led_state = 0;
|
||||
u16 delay = 1;
|
||||
while (delay < LED_DELAY) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(delay);
|
||||
delay++;
|
||||
}
|
||||
LED_PIN_OUT = 0;
|
||||
}
|
||||
|
||||
void tick_250ms(void) {
|
||||
if (timer > 0) {
|
||||
timer--;
|
||||
}
|
||||
if (timer != 0) {
|
||||
turn_on();
|
||||
} else {
|
||||
turn_off();
|
||||
}
|
||||
if (state < 2) {
|
||||
initialize_state();
|
||||
}
|
||||
}
|
||||
|
||||
interrupt(IRQ_UART1_RX_F, uart_recv) {
|
||||
u08 s = UART1.Status;
|
||||
u08 c = UART1.Data;
|
||||
// if (exec == 1) {
|
||||
// switch (c) {
|
||||
// case 0x2A:
|
||||
// timer = 1200;
|
||||
// break;
|
||||
// case 0x2B:
|
||||
// timer = -1;
|
||||
// break;
|
||||
// case 0x2C:
|
||||
// timer = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (c == 0x24) {
|
||||
// exec = 1;
|
||||
// } else {
|
||||
// exec = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
interrupt(IRQ_UART1_TX_C, uart_sent) {
|
||||
cmdPos++;
|
||||
if (cmdPos < cmdLen) {
|
||||
UART1.Data = cmd[cmdPos];
|
||||
} else {
|
||||
cmdPos = 0;
|
||||
cmdLen = 0;
|
||||
memset(cmd, '\0', BUFFER_LEN);
|
||||
UART1.CR2 &= ~UART_CR2_TXE_IVT;
|
||||
}
|
||||
}
|
||||
|
||||
interrupt(IRQ_EXTI_C, touch) {
|
||||
if (PORT_C.IDR.Pin4) {
|
||||
// Mark touch start
|
||||
start_countdown();
|
||||
} else if (is_countdown_active()) {
|
||||
// Get time on release
|
||||
i16 time = elapsed();
|
||||
if (time > LONG_PRESS_MS) {
|
||||
// Make light continuously if pressed for long
|
||||
timer = -1;
|
||||
} else if (time > SHORT_PRESS_MS) {
|
||||
// If it was short touch set timer for enough time
|
||||
timer = 30 * 4; // 30 seconds * 4 (250ms tick)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interrupt(IRQ_TIM1_OVERFLOW, timer1_tick) {
|
||||
TIM1.Status1.UpdateInterruptFlag = 0;
|
||||
#ifdef WATCHDOG
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#endif
|
||||
tick_250ms();
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
// Setup clock (External, 16Mhz)
|
||||
CLK.External.HighSpeedExternalEnable = 1;
|
||||
while (CLK.External.HighSpeedExternalReady == 0) {
|
||||
nop();
|
||||
}
|
||||
CLK.MasterSwitch = HighSpeedExternal;
|
||||
while (CLK.SwitchControl.SwitchInterruptFlag == 0) {
|
||||
nop();
|
||||
}
|
||||
CLK.SwitchControl.SwitchStartStop = 1;
|
||||
CLK.Divider.Prescaler = 0x00;
|
||||
CLK.Divider.HighSpeedPrescaler = 0x00;
|
||||
CLK.Peripheral1.I2C= 0;
|
||||
CLK.Peripheral1.SPI = 0;
|
||||
CLK.Peripheral1.Timer2 = 0;
|
||||
CLK.Peripheral1.Timer4 = 0;
|
||||
CLK.Peripheral2.AnalogDigitalConvertor = 0;
|
||||
|
||||
// Setup UART pins
|
||||
RX_PIN_DIR = 0;
|
||||
RX_PIN_CR1 = 0;
|
||||
RX_PIN_CR2 = 0;
|
||||
TX_PIN_DIR = 1;
|
||||
|
||||
// Setup touch sensor pins
|
||||
PORT_C.DDR.Pin4 = 0;
|
||||
PORT_C.CR1.Pin4 = 0;
|
||||
PORT_C.CR2.Pin4 = 1;
|
||||
EXTI_CR1.PortC = EXTI_RISING_FALLING;
|
||||
|
||||
// Setup UART (115200 8N1, with interupt)
|
||||
// 115200 | 9600 | 57600
|
||||
UART1.CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2);
|
||||
// UART1.BRR2 = 0x0B; // 0x03; // 0x11;
|
||||
// UART1.BRR1 = 0x08; // 0x68; // 0x06;
|
||||
UART1.BRR2 = 0x03;
|
||||
UART1.BRR1 = 0x68;
|
||||
UART1.CR2 = UART_CR2_TEN | UART_CR2_REN | UART_CR2_RXNE_IVT | UART_CR2_SBK;
|
||||
CLK.Peripheral1.Serial1 = 1;
|
||||
|
||||
// Setup LED pin
|
||||
LED_PIN_DIR = 1;
|
||||
LED_PIN_CR1 = 1;
|
||||
LED_PIN_CR2 = 0;
|
||||
LED_PIN_OUT = 1;
|
||||
|
||||
// Setup timer 250ms tick
|
||||
CLK.Peripheral1.Timer1 = 1;
|
||||
const u16 div = 1599;
|
||||
const u16 cou = 2500;
|
||||
TIM1.PrescalerH = div >> 8;
|
||||
TIM1.PrescalerL = div & 0xFF;
|
||||
TIM1.AutoReloadH = cou >> 8;
|
||||
TIM1.AutoReloadL = cou & 0xFF;
|
||||
TIM1.Interrupt.UpdateInterrupt = 1;
|
||||
TIM1.Control1.CounterEnable = 1;
|
||||
|
||||
#ifdef INVERSION
|
||||
LED_PIN_OUT = 1;
|
||||
#else
|
||||
LED_PIN_OUT = 0;
|
||||
#endif
|
||||
|
||||
#ifdef WATCHDOG
|
||||
// Start watchdog
|
||||
IWATCHDOG.Key = IndependWatchdogOn;
|
||||
IWATCHDOG.Key = IndependWatchdogEdit;
|
||||
IWATCHDOG.Prescaler = WatchdogPrescaler_256; // Around 128kHz/256=500Hz=2ms
|
||||
IWATCHDOG.Reload = 0xFF; // 2ms*256=512ms
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#endif
|
||||
|
||||
// Start interrupts
|
||||
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
|
||||
CFG_GCR |= 0x02; // Set AL for disable main();
|
||||
wfi();
|
||||
|
||||
// Infinite worker loop
|
||||
for (;;) {
|
||||
delay_tick(0xff);
|
||||
#ifdef WATCHDOG
|
||||
IWATCHDOG.Key = IndependWatchdogReset;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user