updating "turning off" & test added adc (light)

This commit is contained in:
Vitalii 2025-05-17 21:34:41 +03:00
parent bea5523e02
commit 6f3f8fa6f5
Signed by: SymbX
GPG Key ID: FF51F4E4BCE459EE
2 changed files with 155 additions and 34 deletions

View File

@ -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

View File

@ -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;