updating "turning off" & test added adc (light)
This commit is contained in:
parent
bea5523e02
commit
6f3f8fa6f5
|
|
@ -61,6 +61,16 @@
|
||||||
#define I2C1 (*(volatile I2C*) 0x5210)
|
#define I2C1 (*(volatile I2C*) 0x5210)
|
||||||
#define CLK (*(Clock*) 0x50C0)
|
#define CLK (*(Clock*) 0x50C0)
|
||||||
#define WWDG (*(Watchdog*) 0x50D1)
|
#define WWDG (*(Watchdog*) 0x50D1)
|
||||||
|
#define ADC1_BUFFER0 (*(ADCBuffer*) 0x53E0)
|
||||||
|
#define ADC1_BUFFER1 (*(ADCBuffer*) 0x53E2)
|
||||||
|
#define ADC1_BUFFER2 (*(ADCBuffer*) 0x53E4)
|
||||||
|
#define ADC1_BUFFER3 (*(ADCBuffer*) 0x53E6)
|
||||||
|
#define ADC1_BUFFER4 (*(ADCBuffer*) 0x53E8)
|
||||||
|
#define ADC1_BUFFER5 (*(ADCBuffer*) 0x53EA)
|
||||||
|
#define ADC1_BUFFER6 (*(ADCBuffer*) 0x53EC)
|
||||||
|
#define ADC1_BUFFER7 (*(ADCBuffer*) 0x53EE)
|
||||||
|
#define ADC1_BUFFER8 (*(ADCBuffer*) 0x53F0)
|
||||||
|
#define ADC1_BUFFER9 (*(ADCBuffer*) 0x53F2)
|
||||||
#define ADC1 (*(ADC*) 0x5400)
|
#define ADC1 (*(ADC*) 0x5400)
|
||||||
#define TIM2 (*(GeneralTimer*) 0x5300)
|
#define TIM2 (*(GeneralTimer*) 0x5300)
|
||||||
|
|
||||||
|
|
@ -71,4 +81,4 @@
|
||||||
#define CFG_GCR (*(u08*) 0x7F60)
|
#define CFG_GCR (*(u08*) 0x7F60)
|
||||||
#define IWATCHDOG (*(IndependWatchdog*) 0x50E0)
|
#define IWATCHDOG (*(IndependWatchdog*) 0x50E0)
|
||||||
|
|
||||||
#endif//STM8S103F3_DEF
|
#endif//STM8S103F3_DEF
|
||||||
|
|
|
||||||
177
src/main.c
177
src/main.c
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#define AMOUNT_DISTANCE_MEASURE 8
|
#define AMOUNT_DISTANCE_MEASURE 8
|
||||||
#define ACTIVATION_DISTANCE 40
|
#define ACTIVATION_DISTANCE 40
|
||||||
|
#define MIN_LIGHT 512
|
||||||
|
|
||||||
// LED pin info
|
// LED pin info
|
||||||
#define LED_PIN_DIR PORT_C.DDR.Pin3
|
#define LED_PIN_DIR PORT_C.DDR.Pin3
|
||||||
|
|
@ -31,6 +32,12 @@
|
||||||
#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
|
||||||
|
|
||||||
|
#define LIGHT_PIN_DIR PORT_D.DDR.Pin3
|
||||||
|
#define LIGHT_PIN_CR1 PORT_D.CR1.Pin3
|
||||||
|
#define LIGHT_PIN_CR2 PORT_D.CR2.Pin3
|
||||||
|
#define LIGHT_PIN_OUT PORT_D.ODR.Pin3
|
||||||
|
|
||||||
|
#define LIGHT_CHANNEL 4
|
||||||
#define PRESS_ACTIVATION_TIME 30 * 4
|
#define PRESS_ACTIVATION_TIME 30 * 4
|
||||||
#define SENSE_ACTIVATION_TIME PRESS_ACTIVATION_TIME
|
#define SENSE_ACTIVATION_TIME PRESS_ACTIVATION_TIME
|
||||||
|
|
||||||
|
|
@ -61,6 +68,8 @@ u08 state = 0;
|
||||||
u08 led_state = 0;
|
u08 led_state = 0;
|
||||||
u16 last_distance[AMOUNT_DISTANCE_MEASURE] = {0};
|
u16 last_distance[AMOUNT_DISTANCE_MEASURE] = {0};
|
||||||
u08 distance_count = 0;
|
u08 distance_count = 0;
|
||||||
|
u16 light_level = 1024;
|
||||||
|
u08 disable_until_lost = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hang processor with big delay and hope for watchdog to kick-in or directly
|
* Hang processor with big delay and hope for watchdog to kick-in or directly
|
||||||
|
|
@ -126,12 +135,97 @@ i16 elapsed(void) {
|
||||||
return next / 10 + full_tick * 250;
|
return next / 10 + full_tick * 250;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate average distance from last N measurements
|
||||||
|
* Note: returns 0 if no measurements done
|
||||||
|
*/
|
||||||
|
u16 avg_distance(void) {
|
||||||
|
u16 sum = 0;
|
||||||
|
u08 cnt = 0;
|
||||||
|
for (u08 i = 0; i < AMOUNT_DISTANCE_MEASURE; i++) {
|
||||||
|
sum += last_distance[i];
|
||||||
|
if (last_distance[i] > 0) {
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cnt > 0) {
|
||||||
|
return sum / cnt;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hex_byte(u08 b, u08 p) {
|
||||||
|
tx_buffer[p] = (((b & 0xF0) >> 4) + '0');
|
||||||
|
if (tx_buffer[p] > 57) {
|
||||||
|
tx_buffer[p] += 7;
|
||||||
|
}
|
||||||
|
tx_buffer[p + 1] = ((b & 0x0F) + '0');
|
||||||
|
if (tx_buffer[p + 1] > 57) {
|
||||||
|
tx_buffer[p + 1] += 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void send_some_command(void) {
|
void send_some_command(void) {
|
||||||
tx_buffer[0] = 'C';
|
/*
|
||||||
tx_buffer[1] = 'M';
|
u08 t = (light_level & 0xF000 >> 12) + '0';
|
||||||
tx_buffer[2] = 'D';
|
if (t > 57) {
|
||||||
tx_buffer[3] = '\n';
|
t += 7;
|
||||||
start_cmd(4);
|
}
|
||||||
|
tx_buffer[0] = t;
|
||||||
|
t = (light_level & 0x0F00 >> 8) + '0';
|
||||||
|
if (t > 57) {
|
||||||
|
t += 7;
|
||||||
|
}
|
||||||
|
tx_buffer[1] = t;
|
||||||
|
t = (light_level & 0x00F0 >> 4) + '0';
|
||||||
|
if (t > 57) {
|
||||||
|
t += 7;
|
||||||
|
}
|
||||||
|
tx_buffer[2] = t;
|
||||||
|
t = (light_level & 0x000F >> 0) + '0';
|
||||||
|
if (t > 57) {
|
||||||
|
t += 7;
|
||||||
|
}
|
||||||
|
tx_buffer[3] = t;
|
||||||
|
tx_buffer[4] = '\r';
|
||||||
|
tx_buffer[5] = '\n';
|
||||||
|
start_cmd(6);
|
||||||
|
*/
|
||||||
|
u08 p = 0;
|
||||||
|
tx_buffer[p++] = 'S';
|
||||||
|
tx_buffer[p++] = led_state ? '1' : '0';
|
||||||
|
tx_buffer[p++] = ' ';
|
||||||
|
tx_buffer[p++] = 'T';
|
||||||
|
hex_byte(full_tick, p);
|
||||||
|
p += 2;
|
||||||
|
tx_buffer[p++] = ' ';
|
||||||
|
tx_buffer[p++] = 'X';
|
||||||
|
tx_buffer[p++] = is_countdown_active() ? '1' : '0';
|
||||||
|
tx_buffer[p++] = ' ';
|
||||||
|
tx_buffer[p++] = 'J';
|
||||||
|
tx_buffer[p++] = disable_until_lost + '0';
|
||||||
|
tx_buffer[p++] = ' ';
|
||||||
|
tx_buffer[p++] = 'L';
|
||||||
|
hex_byte(light_level >> 8, p);
|
||||||
|
p += 2;
|
||||||
|
hex_byte(light_level & 0xff, p);
|
||||||
|
p += 2;
|
||||||
|
tx_buffer[p++] = ' ';
|
||||||
|
tx_buffer[p++] = 'D';
|
||||||
|
i16 d = avg_distance();
|
||||||
|
hex_byte(d >> 8, p);
|
||||||
|
p += 2;
|
||||||
|
hex_byte(d & 0xff, p);
|
||||||
|
p += 2;
|
||||||
|
tx_buffer[p++] = ' ';
|
||||||
|
tx_buffer[p++] = 'U';
|
||||||
|
hex_byte(timer >> 8, p);
|
||||||
|
p += 2;
|
||||||
|
hex_byte(timer & 0xff, p);
|
||||||
|
p += 2;
|
||||||
|
tx_buffer[p++] = '\r';
|
||||||
|
tx_buffer[p++] = '\n';
|
||||||
|
start_cmd(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -161,6 +255,7 @@ void turn_on(void) {
|
||||||
}
|
}
|
||||||
led_state = 1;
|
led_state = 1;
|
||||||
u16 delay = LED_FADE_TIME;
|
u16 delay = LED_FADE_TIME;
|
||||||
|
// send_some_command();
|
||||||
while (delay > 1) {
|
while (delay > 1) {
|
||||||
LED_PIN_OUT ^= 1;
|
LED_PIN_OUT ^= 1;
|
||||||
delay_tick(delay);
|
delay_tick(delay);
|
||||||
|
|
@ -179,6 +274,7 @@ void turn_off(void) {
|
||||||
}
|
}
|
||||||
led_state = 0;
|
led_state = 0;
|
||||||
u16 delay = 1;
|
u16 delay = 1;
|
||||||
|
// send_some_command();
|
||||||
while (delay < LED_FADE_TIME) {
|
while (delay < LED_FADE_TIME) {
|
||||||
LED_PIN_OUT ^= 1;
|
LED_PIN_OUT ^= 1;
|
||||||
delay_tick(delay);
|
delay_tick(delay);
|
||||||
|
|
@ -187,25 +283,6 @@ void turn_off(void) {
|
||||||
LED_PIN_OUT = 0;
|
LED_PIN_OUT = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate average distance from last N measurements
|
|
||||||
* Note: returns 0 if no measurements done
|
|
||||||
*/
|
|
||||||
u16 avg_distance(void) {
|
|
||||||
u16 sum = 0;
|
|
||||||
u08 cnt = 0;
|
|
||||||
for (u08 i = 0; i < AMOUNT_DISTANCE_MEASURE; i++) {
|
|
||||||
sum += last_distance[i];
|
|
||||||
if (last_distance[i] > 0) {
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cnt > 0) {
|
|
||||||
return sum / cnt;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tick event handler
|
* Tick event handler
|
||||||
*/
|
*/
|
||||||
|
|
@ -216,6 +293,9 @@ void tick_250ms(void) {
|
||||||
// and skip other tasks if not finished
|
// and skip other tasks if not finished
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
CLK.Peripheral2.AnalogDigitalConvertor = 1;
|
||||||
|
delay_tick(0x20);
|
||||||
|
ADC1.Configuration1.ConverterOn = 1;
|
||||||
if (is_countdown_active() && full_tick < 255) {
|
if (is_countdown_active() && full_tick < 255) {
|
||||||
full_tick++;
|
full_tick++;
|
||||||
}
|
}
|
||||||
|
|
@ -225,13 +305,17 @@ void tick_250ms(void) {
|
||||||
}
|
}
|
||||||
if (timer == 0) {
|
if (timer == 0) {
|
||||||
u16 distance = avg_distance();
|
u16 distance = avg_distance();
|
||||||
if (distance != 0 && distance < ACTIVATION_DISTANCE) {
|
if (distance != 0) {
|
||||||
timer = SENSE_ACTIVATION_TIME;
|
if (disable_until_lost == 0 && light_level <= MIN_LIGHT && distance < ACTIVATION_DISTANCE) {
|
||||||
|
timer = SENSE_ACTIVATION_TIME;
|
||||||
|
} else if (distance >= ACTIVATION_DISTANCE) {
|
||||||
|
disable_until_lost = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elapsed() > LONG_PRESS_MS) {
|
||||||
|
timer = -1;
|
||||||
|
stop_countdown();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (elapsed() > LONG_PRESS_MS) {
|
|
||||||
timer = -1;
|
|
||||||
stop_countdown();
|
|
||||||
}
|
}
|
||||||
// If we still have time
|
// If we still have time
|
||||||
// note: timer can be below zero to work without timer
|
// note: timer can be below zero to work without timer
|
||||||
|
|
@ -254,7 +338,7 @@ int is_rx_finished(void) {
|
||||||
}
|
}
|
||||||
// Check head, tail and just in case - length
|
// Check head, tail and just in case - length
|
||||||
return
|
return
|
||||||
(rx_buffer[0] == RANGE[0] &&
|
(rx_buffer[0] == RANGE[0] &&
|
||||||
rx_buffer[1] == RANGE[1] &&
|
rx_buffer[1] == RANGE[1] &&
|
||||||
rx_buffer[2] == RANGE[2] &&
|
rx_buffer[2] == RANGE[2] &&
|
||||||
rx_buffer[3] == RANGE[3] &&
|
rx_buffer[3] == RANGE[3] &&
|
||||||
|
|
@ -280,7 +364,7 @@ void add_distance(u16 distance) {
|
||||||
*/
|
*/
|
||||||
void process_rx(void) {
|
void process_rx(void) {
|
||||||
if (rx_buffer[0] == RANGE[0]) {
|
if (rx_buffer[0] == RANGE[0]) {
|
||||||
u16 distance = 0;
|
u16 distance = 0;
|
||||||
for (u08 i = 6; i <= rx_pos; i++) {
|
for (u08 i = 6; i <= rx_pos; i++) {
|
||||||
if (rx_buffer[i] >= '0' && rx_buffer[i] <= '9') {
|
if (rx_buffer[i] >= '0' && rx_buffer[i] <= '9') {
|
||||||
distance = distance * 10 + (rx_buffer[i] - '0');
|
distance = distance * 10 + (rx_buffer[i] - '0');
|
||||||
|
|
@ -355,6 +439,7 @@ interrupt(IRQ_EXTI_C, touch) {
|
||||||
timer = PRESS_ACTIVATION_TIME; // 30 seconds * 4 (250ms tick)
|
timer = PRESS_ACTIVATION_TIME; // 30 seconds * 4 (250ms tick)
|
||||||
} else {
|
} else {
|
||||||
// Or turn it off
|
// Or turn it off
|
||||||
|
disable_until_lost = 1;
|
||||||
timer = 0;
|
timer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -369,6 +454,16 @@ interrupt(IRQ_TIM1_OVERFLOW, timer1_tick) {
|
||||||
tick_250ms();
|
tick_250ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interrupt(IRQ_ADC_END, adc_done) {
|
||||||
|
u08 low = ADC.Data.Low;
|
||||||
|
u08 high = ADC.Data.High;
|
||||||
|
if (ADC1.Configuration3.OverrunFlag == 0) {
|
||||||
|
light_level = (high << 8) | low;
|
||||||
|
// send_some_command();
|
||||||
|
}
|
||||||
|
ADC1.ControlStatus.EndOfConversion = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// Setup clock (External, 16Mhz)
|
// Setup clock (External, 16Mhz)
|
||||||
CLK.External.HighSpeedExternalEnable = 1;
|
CLK.External.HighSpeedExternalEnable = 1;
|
||||||
|
|
@ -387,7 +482,6 @@ void main(void) {
|
||||||
CLK.Peripheral1.SPI = 0;
|
CLK.Peripheral1.SPI = 0;
|
||||||
CLK.Peripheral1.Timer2 = 0;
|
CLK.Peripheral1.Timer2 = 0;
|
||||||
CLK.Peripheral1.Timer4 = 0;
|
CLK.Peripheral1.Timer4 = 0;
|
||||||
CLK.Peripheral2.AnalogDigitalConvertor = 0;
|
|
||||||
|
|
||||||
// Setup UART pins
|
// Setup UART pins
|
||||||
RX_PIN_DIR = 0;
|
RX_PIN_DIR = 0;
|
||||||
|
|
@ -401,6 +495,10 @@ void main(void) {
|
||||||
PORT_C.CR2.Pin4 = 1;
|
PORT_C.CR2.Pin4 = 1;
|
||||||
EXTI_CR1.PortC = EXTI_RISING_FALLING;
|
EXTI_CR1.PortC = EXTI_RISING_FALLING;
|
||||||
|
|
||||||
|
LIGHT_PIN_DIR = 0;
|
||||||
|
LIGHT_PIN_CR1 = 0;
|
||||||
|
LIGHT_PIN_CR2 = 0;
|
||||||
|
|
||||||
// Setup UART (115200 8N1, with interupt)
|
// Setup UART (115200 8N1, with interupt)
|
||||||
// 115200 | 9600 | 57600
|
// 115200 | 9600 | 57600
|
||||||
UART1.CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2);
|
UART1.CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2);
|
||||||
|
|
@ -417,6 +515,19 @@ void main(void) {
|
||||||
LED_PIN_CR2 = 0;
|
LED_PIN_CR2 = 0;
|
||||||
LED_PIN_OUT = 1;
|
LED_PIN_OUT = 1;
|
||||||
|
|
||||||
|
|
||||||
|
// Setup ADC
|
||||||
|
CLK.Peripheral2.AnalogDigitalConvertor = 1;
|
||||||
|
ADC1.Configuration2.Alignment = 1;
|
||||||
|
ADC1.Configuration1.ContinousConversion = 0;
|
||||||
|
ADC1.ControlStatus.Channel = 0;
|
||||||
|
ADC1.ControlStatus.Channel = LIGHT_CHANNEL;
|
||||||
|
ADC1.Configuration1.Prescaler = 7;
|
||||||
|
ADC1.Configuration2.ExternalTrigger = 0;
|
||||||
|
ADC1.SchmittDisable.High = 0x3f;
|
||||||
|
ADC1.SchmittDisable.Low = 0xb3;
|
||||||
|
ADC1.ControlStatus.Interrupt = 1;
|
||||||
|
|
||||||
// Setup timer 250ms tick
|
// Setup timer 250ms tick
|
||||||
CLK.Peripheral1.Timer1 = 1;
|
CLK.Peripheral1.Timer1 = 1;
|
||||||
const u16 div = 1599;
|
const u16 div = 1599;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue