application: show multiple changes when monitoring (and rate limit output)

This commit is contained in:
King Kévin 2021-05-03 12:39:46 +02:00
parent 436c925038
commit f603b1398e
1 changed files with 46 additions and 22 deletions

View File

@ -424,7 +424,8 @@ static void command_monitor(void* argument)
}
}
// get initial state
// show help
puts("'x' shows multiple changes\n");
puts("press any key to stop monitoring\n");
puts("time (s) ");
for (uint8_t i = channel_start; i <= channel_stop; i++) {
@ -438,15 +439,22 @@ static void command_monitor(void* argument)
timer_disable_counter(TIM(MONITOR_TIMER)); // disable timer to configure it
timer_set_mode(TIM(MONITOR_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
timer_set_prescaler(TIM(MONITOR_TIMER), (rcc_ahb_frequency / 2000) - 1); // generate half millisecond ticks (prescaler is not large enough for milliseconds)
timer_set_period(TIM(MONITOR_TIMER), 2000 - 1); // set period to seconds
timer_set_period(TIM(MONITOR_TIMER), 200 - 1); // set period to 0.1 seconds
timer_clear_flag(TIM(MONITOR_TIMER), TIM_SR_UIF); // clear update (overflow) flag
timer_update_on_overflow(TIM(MONITOR_TIMER)); // only use counter overflow as UEV source (use overflow as start time or timeout)
uint32_t seconds = 0; // count the seconds using the overflow
uint32_t seconds = 0; // count the 0.1 seconds using the overflow
timer_enable_counter(TIM(MONITOR_TIMER)); // enable timer
// start monitoring
uint16_t gpioa_data = UINT16_MAX;
uint16_t gpiob_data = UINT16_MAX;
uint16_t gpioa_old = UINT16_MAX; // the current level on the port where some channels are
uint16_t gpiob_old = UINT16_MAX; // since not all pins of the port care used for the channel, initializing to 0xffff will force an update to the actual data
bool channel_changed = false; // if a channel changed
uint8_t channels_changed[CHANNEL_NUMBERS] = {0}; // how many times a channel changed
bool channels_level[CHANNEL_NUMBERS]; // the level of the channels
for (uint8_t i = channel_start; i <= channel_stop; i++) { // initialize level of channels
const uint16_t port = (GPIOA == channel_ports[i] ? gpioa_old : gpiob_old); // get the port on which the channel is
channels_level[i] = (port & channel_pins[i]); // get the pin level on which the channel is
}
while (!user_input_available) { // run until user breaks it
// time to do periodic checks
if (wakeup_flag || second_flag) {
@ -454,31 +462,47 @@ static void command_monitor(void* argument)
wakeup_flag = false; // clear flag
second_flag = false; // clear flag
}
// one second has passed
if (timer_get_flag(TIM(MONITOR_TIMER), TIM_SR_UIF)) {
if (timer_get_flag(TIM(MONITOR_TIMER), TIM_SR_UIF)) { // 0.1 second has passed
timer_clear_flag(TIM(MONITOR_TIMER), TIM_SR_UIF); // clear flag
seconds++; // count the second
seconds++; // count the 0.1 seconds
if (channel_changed) { // there was some activity
// we print the change every 0.1 s instead of synchronously to rate limit the print (and overfill the buffer)
printf("%04u.%01u ", seconds / 10, seconds % 10); // print current time stamp (change time stamp with 0.1s precision
for (uint8_t i = channel_start; i <= channel_stop; i++) { // print level of each change
putc(' '); // start new channel
if (channels_changed[i] > 1) { // channel changed more than once
putc('x'); // show multiple changes
} else {
putc(' '); // show no or single change
}
if (channels_level[i]) { // high level
putc('1');
} else {
putc('0');
}
channels_changed[i] = 0; // clear number of changes
}
puts("\n");
channel_changed = false; // clear flag
}
}
// check is there is a change on a channel
const uint16_t gpioa_new = gpio_get(GPIOA, gpioa_mask);
const uint16_t gpiob_new = gpio_get(GPIOB, gpioa_mask);
if (gpioa_new != gpioa_data || gpiob_new != gpiob_data) {
// print data
printf("%04u.%03u", seconds, timer_get_counter(TIM(MONITOR_TIMER)) / 2);
for (uint8_t i = channel_start; i <= channel_stop; i++) {
const uint16_t port = (GPIOA == channel_ports[i] ? gpioa_new : gpiob_new);
const uint8_t high = ((port & channel_pins[i]) ? 1 : 0);
if (high) {
puts(" 1");
} else {
puts(" 0");
if (gpioa_new != gpioa_old || gpiob_new != gpiob_old) { // some GPIO changed (should be channel data)
for (uint8_t i = channel_start; i <= channel_stop; i++) { // check which channel changed
const uint16_t port = (GPIOA == channel_ports[i] ? gpioa_new : gpiob_new); // get the port on which the channel is
const bool pin = (port & channel_pins[i]); // get the pin level on which the channel is
if (pin != channels_level[i]) { // data on this channel changed
channel_changed = true; // remember one channel changed
channels_changed[i]++; // remember how many times this channel changed
channels_level[i] = pin; // save new level
}
}
puts("\n");
// save change
gpioa_data = gpioa_new;
gpiob_data = gpiob_new;
// do we need a rate limit?
gpioa_old = gpioa_new;
gpiob_old = gpiob_new;
}
}
user_input_get(); // clean input