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 CLK (*(Clock*) 0x50C0)
|
||||
#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 TIM2 (*(GeneralTimer*) 0x5300)
|
||||
|
||||
|
|
@ -71,4 +81,4 @@
|
|||
#define CFG_GCR (*(u08*) 0x7F60)
|
||||
#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 ACTIVATION_DISTANCE 40
|
||||
#define MIN_LIGHT 512
|
||||
|
||||
// LED pin info
|
||||
#define LED_PIN_DIR PORT_C.DDR.Pin3
|
||||
|
|
@ -31,6 +32,12 @@
|
|||
#define TX_PIN_CR2 PORT_D.CR2.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 SENSE_ACTIVATION_TIME PRESS_ACTIVATION_TIME
|
||||
|
||||
|
|
@ -61,6 +68,8 @@ u08 state = 0;
|
|||
u08 led_state = 0;
|
||||
u16 last_distance[AMOUNT_DISTANCE_MEASURE] = {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
|
||||
|
|
@ -126,12 +135,97 @@ i16 elapsed(void) {
|
|||
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) {
|
||||
tx_buffer[0] = 'C';
|
||||
tx_buffer[1] = 'M';
|
||||
tx_buffer[2] = 'D';
|
||||
tx_buffer[3] = '\n';
|
||||
start_cmd(4);
|
||||
/*
|
||||
u08 t = (light_level & 0xF000 >> 12) + '0';
|
||||
if (t > 57) {
|
||||
t += 7;
|
||||
}
|
||||
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;
|
||||
u16 delay = LED_FADE_TIME;
|
||||
// send_some_command();
|
||||
while (delay > 1) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(delay);
|
||||
|
|
@ -179,6 +274,7 @@ void turn_off(void) {
|
|||
}
|
||||
led_state = 0;
|
||||
u16 delay = 1;
|
||||
// send_some_command();
|
||||
while (delay < LED_FADE_TIME) {
|
||||
LED_PIN_OUT ^= 1;
|
||||
delay_tick(delay);
|
||||
|
|
@ -187,25 +283,6 @@ void turn_off(void) {
|
|||
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
|
||||
*/
|
||||
|
|
@ -216,6 +293,9 @@ void tick_250ms(void) {
|
|||
// and skip other tasks if not finished
|
||||
return;
|
||||
}
|
||||
CLK.Peripheral2.AnalogDigitalConvertor = 1;
|
||||
delay_tick(0x20);
|
||||
ADC1.Configuration1.ConverterOn = 1;
|
||||
if (is_countdown_active() && full_tick < 255) {
|
||||
full_tick++;
|
||||
}
|
||||
|
|
@ -225,13 +305,17 @@ void tick_250ms(void) {
|
|||
}
|
||||
if (timer == 0) {
|
||||
u16 distance = avg_distance();
|
||||
if (distance != 0 && distance < ACTIVATION_DISTANCE) {
|
||||
timer = SENSE_ACTIVATION_TIME;
|
||||
if (distance != 0) {
|
||||
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
|
||||
// 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
|
||||
return
|
||||
(rx_buffer[0] == RANGE[0] &&
|
||||
(rx_buffer[0] == RANGE[0] &&
|
||||
rx_buffer[1] == RANGE[1] &&
|
||||
rx_buffer[2] == RANGE[2] &&
|
||||
rx_buffer[3] == RANGE[3] &&
|
||||
|
|
@ -280,7 +364,7 @@ void add_distance(u16 distance) {
|
|||
*/
|
||||
void process_rx(void) {
|
||||
if (rx_buffer[0] == RANGE[0]) {
|
||||
u16 distance = 0;
|
||||
u16 distance = 0;
|
||||
for (u08 i = 6; i <= rx_pos; i++) {
|
||||
if (rx_buffer[i] >= '0' && rx_buffer[i] <= '9') {
|
||||
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)
|
||||
} else {
|
||||
// Or turn it off
|
||||
disable_until_lost = 1;
|
||||
timer = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -369,6 +454,16 @@ interrupt(IRQ_TIM1_OVERFLOW, timer1_tick) {
|
|||
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) {
|
||||
// Setup clock (External, 16Mhz)
|
||||
CLK.External.HighSpeedExternalEnable = 1;
|
||||
|
|
@ -387,7 +482,6 @@ void main(void) {
|
|||
CLK.Peripheral1.SPI = 0;
|
||||
CLK.Peripheral1.Timer2 = 0;
|
||||
CLK.Peripheral1.Timer4 = 0;
|
||||
CLK.Peripheral2.AnalogDigitalConvertor = 0;
|
||||
|
||||
// Setup UART pins
|
||||
RX_PIN_DIR = 0;
|
||||
|
|
@ -401,6 +495,10 @@ void main(void) {
|
|||
PORT_C.CR2.Pin4 = 1;
|
||||
EXTI_CR1.PortC = EXTI_RISING_FALLING;
|
||||
|
||||
LIGHT_PIN_DIR = 0;
|
||||
LIGHT_PIN_CR1 = 0;
|
||||
LIGHT_PIN_CR2 = 0;
|
||||
|
||||
// Setup UART (115200 8N1, with interupt)
|
||||
// 115200 | 9600 | 57600
|
||||
UART1.CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2);
|
||||
|
|
@ -417,6 +515,19 @@ void main(void) {
|
|||
LED_PIN_CR2 = 0;
|
||||
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
|
||||
CLK.Peripheral1.Timer1 = 1;
|
||||
const u16 div = 1599;
|
||||
|
|
|
|||
Loading…
Reference in New Issue