Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Core/Src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static void MX_TIM3_Init(void);
void StartDefaultTask(void *argument);

/* USER CODE BEGIN PFP */

void buzzer_manager_task(void *);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
Expand Down Expand Up @@ -158,6 +158,13 @@ int main(void)

ul_ulog_init();

static const osThreadAttr_t buzzer_task_attrs = {
.name = "buzzer",
.stack_size = 64 * 4,
.priority = (osPriority_t) osPriorityHigh,
};
(void) osThreadNew(buzzer_manager_task, NULL, &buzzer_task_attrs);


/* USER CODE END RTOS_THREADS */

Expand Down
284 changes: 284 additions & 0 deletions KPI_Rover/Buzzer/driver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
#include <stddef.h>

#include "stm32f4xx_hal.h"

#include "generic.h"
#include "driver.h"

#define BUZZER_BLOCKING_TIME_LIMIT 1000

#define CHECK_ERROR(condition, err_value) do { \
if (condition) { \
errors = (err_value); \
goto fail; \
} \
} while (0)


static uint8_t count_bits_16bit(uint16_t value)
{
uint8_t result = 0;

for ( ; value; value >>= 1)
result += value & 1;

return result;
}

static uint32_t Buzzer_SetON(struct BuzzerObject * const self)
{
uint32_t errors = 0;

CHECK_ERROR(!self->c.initialized, BUZZER_NOT_INITIALIZED_ERROR);

HAL_GPIO_WritePin(self->c.GPIO_port, self->c.GPIO_pin, GPIO_PIN_SET);

fail:
return errors;
}

static uint32_t Buzzer_SetOFF(struct BuzzerObject * const self)
{
uint32_t errors = 0;

CHECK_ERROR(!self->c.initialized, BUZZER_NOT_INITIALIZED_ERROR);

HAL_GPIO_WritePin(self->c.GPIO_port, self->c.GPIO_pin, GPIO_PIN_RESET);

fail:
return errors;
}


static void Buzzer_OFF_Enter(struct BuzzerObject * const self, const struct BuzzerEvent * const ev)
{
Buzzer_SetOFF(self);
}

static void Buzzer_OFF_Handle(struct BuzzerObject * const self)
{

}

static void Buzzer_OFF_Leave(struct BuzzerObject * const self)
{
Buzzer_SetOFF(self);
}


static void Buzzer_ON_Enter(struct BuzzerObject * const self, const struct BuzzerEvent * const ev)
{
Buzzer_SetON(self);
}

static void Buzzer_ON_Handle(struct BuzzerObject * const self)
{

}

static void Buzzer_ON_Leave(struct BuzzerObject * const self)
{
Buzzer_SetON(self);
}


static void Buzzer_PULSE_Enter(struct BuzzerObject * const self, const struct BuzzerEvent * const ev)
{
self->ps.config.pulse_on_for = ev->pulse_on_for;
self->ps.config.pulse_off_for = ev->pulse_off_for;
self->ps.config.pulse_total_for = ev->pulse_total_for;

self->ps.current_state = BUZZER_TO_ON;
}

static void Buzzer_PULSE_Handle(struct BuzzerObject * const self)
{
uint32_t tss;

switch (self->ps.current_state) {
case BUZZER_TO_ON:
Buzzer_SetON(self);
self->ps.current_state_since = HAL_GetTick();

tss = ticks_elapsed_since(self->s.current_state_since);

if ((tss + self->ps.config.pulse_on_for) >= self->ps.config.pulse_total_for) {
self->ps.current_state = BUZZER_FINAL_DELAY;
self->ps.state_lifetime_override = self->ps.config.pulse_total_for - tss;
} else {
self->ps.current_state = BUZZER_DELAY_BEFORE_OFF;
}

break;
case BUZZER_DELAY_BEFORE_OFF:
if (ticks_elapsed_since(self->ps.current_state_since) >= self->ps.config.pulse_on_for)
self->ps.current_state = BUZZER_TO_OFF;

break;
case BUZZER_TO_OFF:
Buzzer_SetOFF(self);
self->ps.current_state_since = HAL_GetTick();

tss = ticks_elapsed_since(self->s.current_state_since);

if ((tss + self->ps.config.pulse_off_for) >= self->ps.config.pulse_total_for) {
self->ps.current_state = BUZZER_FINAL_DELAY;
self->ps.state_lifetime_override = self->ps.config.pulse_total_for - tss;
} else {
self->ps.current_state = BUZZER_DELAY_BEFORE_ON;
}

break;
case BUZZER_DELAY_BEFORE_ON:
if (ticks_elapsed_since(self->ps.current_state_since) >= self->ps.config.pulse_off_for)
self->ps.current_state = BUZZER_TO_ON;

break;
case BUZZER_FINAL_DELAY:
if (ticks_elapsed_since(self->ps.current_state_since) < self->ps.state_lifetime_override)
break;

self->e.ev = TO_OFF;
break;
}
}

static void Buzzer_PULSE_Leave(struct BuzzerObject * const self)
{
Buzzer_SetOFF(self);
}


static void Buzzer_Reset(struct BuzzerObject * const self)
{
switch (self->s.current_state) {
case BUZZER_OFF:
Buzzer_OFF_Leave(self);
break;
case BUZZER_ON:
Buzzer_ON_Leave(self);
break;
case BUZZER_PULSE:
Buzzer_PULSE_Leave(self);
break;
case IMPOSSIBLE_STATE:
default:
break;
}

self->s.current_state = BUZZER_OFF;
}

static void Buzzer_ProcessEvent(struct BuzzerObject * const self)
{
if (self->e.ev == NO_EVENT || self->e.ev == IMPOSSIBLE_EVENT)
return;

switch (self->s.current_state) {
case BUZZER_ON:
Buzzer_ON_Leave(self);
break;
case BUZZER_OFF:
Buzzer_OFF_Leave(self);
break;
case BUZZER_PULSE:
Buzzer_PULSE_Leave(self);
break;
default:
break;
}

switch (self->e.ev) {
case TO_ON:
self->s.current_state = BUZZER_ON;
Buzzer_ON_Enter(self, &(self->e));
break;
case TO_OFF:
self->s.current_state = BUZZER_OFF;
Buzzer_OFF_Enter(self, &(self->e));
break;
case TO_PULSE:
self->s.current_state = BUZZER_PULSE;
Buzzer_PULSE_Enter(self, &(self->e));
break;
default:
self->s.current_state = IMPOSSIBLE_STATE;
break;
}

self->s.current_state_since = HAL_GetTick();
self->e.ev = NO_EVENT;
}


uint32_t Buzzer_ConfigurePort(struct BuzzerObject * const self, const GPIO_TypeDef * const gpio_port, const uint16_t gpio_pin)
{
Buzzer_Reset(self);

uint32_t errors = 0;

CHECK_ERROR(count_bits_16bit(gpio_pin) != 1, BUZZER_PIN_ERROR);

self->c.GPIO_port = (GPIO_TypeDef *) gpio_port;
self->c.GPIO_pin = (uint16_t) gpio_pin;

self->c.initialized = 1;

return errors;

fail:
self->c.initialized = 0;
return errors;
}


uint32_t Buzzer_Enable(struct BuzzerObject * const self)
{
self->e.ev = TO_ON;
return 0;
}

uint32_t Buzzer_Disable(struct BuzzerObject * const self)
{
self->e.ev = TO_OFF;
return 0;
}

uint32_t Buzzer_Pulse(struct BuzzerObject * const self, const uint32_t on_time_ms, const uint32_t period_time_ms, const uint32_t total_active_time_ms)
{
uint32_t errors = 0;

const uint32_t off_time_ms = period_time_ms - on_time_ms;

CHECK_ERROR(!on_time_ms, BUZZER_ZERO_ONTIME_ERROR);
CHECK_ERROR(!off_time_ms, BUZZER_ZERO_OFFTIME_ERROR);
CHECK_ERROR(!total_active_time_ms, BUZZER_ZERO_ACTIVE_TIME_ERROR);

self->e.pulse_on_for = on_time_ms;
self->e.pulse_off_for = off_time_ms;
self->e.pulse_total_for = total_active_time_ms;

self->e.ev = TO_PULSE;

fail:
return errors;
}

void Buzzer_TimerTask(struct BuzzerObject * const self)
{
(void) Buzzer_ProcessEvent(self);

switch (self->s.current_state) {
case BUZZER_OFF:
Buzzer_OFF_Handle(self);
break;
case BUZZER_ON:
Buzzer_ON_Handle(self);
break;
case BUZZER_PULSE:
Buzzer_PULSE_Handle(self);
break;
default:
break;
}
}
86 changes: 86 additions & 0 deletions KPI_Rover/Buzzer/driver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#ifndef __BUZZER_DRIVER
#define __BUZZER_DRIVER

#include "stm32f4xx_hal.h"

#define BUZZER_PIN_ERROR 0x1U
#define BUZZER_NOT_INITIALIZED_ERROR 0x2U
#define BUZZER_HAL_ERROR 0x3U
#define BUZZER_VALUE_ERROR 0x4U
#define BUZZER_ZERO_ONTIME_ERROR 0x5U
#define BUZZER_ZERO_OFFTIME_ERROR 0x6U
#define BUZZER_ZERO_ACTIVE_TIME_ERROR 0x7U
#define BUZZER_TIMER_BUSY 0x8U


enum BuzzerEventType {
NO_EVENT,
IMPOSSIBLE_EVENT,
TO_ON,
TO_OFF,
TO_PULSE
};

struct BuzzerEvent {
enum BuzzerEventType ev;
uint32_t pulse_on_for;
uint32_t pulse_off_for;
uint32_t pulse_total_for;
};


enum BuzzerGlobalStateType {
IMPOSSIBLE_STATE,
BUZZER_OFF,
BUZZER_ON,
BUZZER_PULSE
};

struct BuzzerGlobalState {
enum BuzzerGlobalStateType current_state;
uint32_t current_state_since;
};


enum BuzzerPulseSubStateType {
BUZZER_TO_ON,
BUZZER_DELAY_BEFORE_OFF,
BUZZER_TO_OFF,
BUZZER_DELAY_BEFORE_ON,
BUZZER_FINAL_DELAY
};

struct BuzzerPulseConfig {
uint32_t pulse_on_for;
uint32_t pulse_off_for;
uint32_t pulse_total_for;
};

struct BuzzerPulseSubState {
enum BuzzerPulseSubStateType current_state;
struct BuzzerPulseConfig config;
uint32_t current_state_since;
uint32_t state_lifetime_override;
};


struct BuzzerConfig {
GPIO_TypeDef *GPIO_port;
uint16_t GPIO_pin;
int8_t initialized;
};

struct BuzzerObject {
struct BuzzerConfig c;
struct BuzzerGlobalState s;
struct BuzzerPulseSubState ps;
struct BuzzerEvent e;
};

uint32_t Buzzer_ConfigurePort(struct BuzzerObject * const self, const GPIO_TypeDef * const gpio_port, const uint16_t gpio_pin);
uint32_t Buzzer_Enable(struct BuzzerObject * const self);
uint32_t Buzzer_Disable(struct BuzzerObject * const self);
uint32_t Buzzer_Pulse(struct BuzzerObject * const self, const uint32_t on_time_ms, const uint32_t period_time_ms, const uint32_t total_active_time_ms);
void Buzzer_TimerTask(struct BuzzerObject * const self);

#endif /* __BUZZER_DRIVER */
Loading