application: show multiple changes when monitoring (and rate limit output)
This commit is contained in:
parent
436c925038
commit
f603b1398e
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue