sweep feature added
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file sweep.c
|
||||
* @brief Periodic staircase sweep state machine.
|
||||
*/
|
||||
|
||||
#include "sweep.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
bool sweep_start(sweep_t *sweep, const sweep_config_t *config, uint32_t tick_us)
|
||||
{
|
||||
if ((sweep == NULL) || (config == NULL) || (tick_us == 0u) ||
|
||||
(config->min_code > config->max_code) || (config->step_code == 0u) ||
|
||||
(config->step_period_us < tick_us))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sweep->min_code = config->min_code;
|
||||
sweep->max_code = config->max_code;
|
||||
sweep->step_code = config->step_code;
|
||||
sweep->step_ticks = config->step_period_us / tick_us;
|
||||
sweep->pause_ticks = ((uint32_t)config->pause_ms * 1000u) / tick_us;
|
||||
sweep->next_code = config->min_code;
|
||||
sweep->countdown_ticks = 1u;
|
||||
sweep->enabled = 1u;
|
||||
return true;
|
||||
}
|
||||
|
||||
void sweep_stop(sweep_t *sweep)
|
||||
{
|
||||
if (sweep != NULL)
|
||||
{
|
||||
sweep->enabled = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
bool sweep_tick(sweep_t *sweep, uint16_t *out_code)
|
||||
{
|
||||
if ((sweep->enabled == 0u) || (--sweep->countdown_ticks != 0u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*out_code = (uint16_t)sweep->next_code;
|
||||
sweep->countdown_ticks = sweep->step_ticks;
|
||||
if (sweep->next_code == sweep->min_code)
|
||||
{
|
||||
/* The lower bound is held for the inter-sweep pause. */
|
||||
sweep->countdown_ticks += sweep->pause_ticks;
|
||||
}
|
||||
|
||||
if (sweep->next_code >= sweep->max_code)
|
||||
{
|
||||
sweep->next_code = sweep->min_code;
|
||||
}
|
||||
else
|
||||
{
|
||||
sweep->next_code += sweep->step_code;
|
||||
if (sweep->next_code > sweep->max_code)
|
||||
{
|
||||
sweep->next_code = sweep->max_code;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file sweep.h
|
||||
* @brief Hardware-agnostic periodic staircase sweep between two output codes.
|
||||
*
|
||||
* The output steps from `min_code` up to `max_code` (inclusive) every step
|
||||
* period, then returns to `min_code` and holds it for an extra pause before
|
||||
* the next sweep starts.
|
||||
*/
|
||||
|
||||
#ifndef SWEEP_H
|
||||
#define SWEEP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Host-supplied sweep parameters.
|
||||
*/
|
||||
typedef struct sweep_config_t {
|
||||
uint16_t min_code;
|
||||
uint16_t max_code;
|
||||
uint16_t step_code;
|
||||
uint16_t step_period_us;
|
||||
uint16_t pause_ms;
|
||||
} sweep_config_t;
|
||||
|
||||
/**
|
||||
* @brief Sweep state advanced from the periodic tick interrupt.
|
||||
*/
|
||||
typedef struct sweep_t {
|
||||
uint8_t enabled;
|
||||
uint16_t min_code;
|
||||
uint16_t max_code;
|
||||
uint16_t step_code;
|
||||
uint32_t step_ticks;
|
||||
uint32_t pause_ticks;
|
||||
uint32_t next_code;
|
||||
uint32_t countdown_ticks;
|
||||
} sweep_t;
|
||||
|
||||
/**
|
||||
* @brief Validate the configuration and start sweeping from `min_code` on the next tick.
|
||||
*
|
||||
* @return false (sweep left stopped) if bounds, step or period are invalid.
|
||||
*/
|
||||
bool sweep_start(sweep_t *sweep, const sweep_config_t *config, uint32_t tick_us);
|
||||
|
||||
void sweep_stop(sweep_t *sweep);
|
||||
|
||||
/**
|
||||
* @brief Advance the sweep by one tick.
|
||||
*
|
||||
* @return true when `*out_code` holds a new value that must be written to the output.
|
||||
*/
|
||||
bool sweep_tick(sweep_t *sweep, uint16_t *out_code);
|
||||
|
||||
#endif /* SWEEP_H */
|
||||
Reference in New Issue
Block a user