Commit f181b0fd authored by Jacob Priddy's avatar Jacob Priddy 👌

finish latch stuff

parent 8e09bee1
Pipeline #9532 passed with stages
in 1 minute and 23 seconds
......@@ -12,19 +12,20 @@ typedef enum {
DOOR_LATCH_OPENED = 1,
} door_latch_state_t;
/**
* @brief Function is triggered when the door opens or closes
* and takes the state the door currently is in as well as how many
* latch check periods have gone by (currently 1/10'th of a second)
* since it was last opened/closed/when the thread booted
*/
typedef void (* door_latch_event_cb)(door_latch_state_t state, uint64_t);
typedef void* door_latch_event_handle_t;
door_latch_event_handle_t door_latch_register_watch(door_latch_event_cb);
void door_latch_unregister_watch(door_latch_event_handle_t);
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
///**
// * @brief Function is triggered when the door opens or closes
// * and takes the state the door currently is in as well as how many
// * latch check periods have gone by (currently 1/10'th of a second)
// * since it was last opened/closed/when the thread booted
// */
//typedef void (* door_latch_event_cb)(door_latch_state_t state, uint64_t);
//
//typedef void* door_latch_event_handle_t;
//
//door_latch_event_handle_t door_latch_register_watch(door_latch_event_cb);
//
//void door_latch_unregister_watch(door_latch_event_handle_t);
void door_latch_watch_task(void*);
......
......@@ -24,6 +24,7 @@
#include "app/keypad.h"
#include "app/state.h"
#include "app/status.h"
#include "app/latch.h"
static const char* TAG = "MAIN_MODULE";
static volatile bool door_request_done;
......@@ -85,7 +86,8 @@ void initialize(void)
door_token_initialize(API_TOKEN);
// Setup the RTOS interfaces such as events
door_rtos_initialize();
// Needs RTOS
// Needs just RTOS
door_latch_initialize();
door_keypad_initialize();
// Start up WiFi (WiFi uses tokens and the RTOS events)
......@@ -98,11 +100,15 @@ void initialize(void)
// Needs the API
door_status_initialize();
}
void start(void)
{
xTaskCreate(door_api_handle_requests_task, "api_task", 4096, NULL, 5, NULL);
// Processing HTTP request and getting codes back is probably the most important
// for noticable responsiveness
xTaskCreate(door_api_handle_requests_task, "api_task", 4096, NULL, 7, NULL);
xTaskCreate(door_latch_watch_task, "latch_task", 4096, NULL, 4, NULL);
xTaskCreate(door_lock_task, "lock_task", 4096, NULL, 6, NULL);
xTaskCreate(door_keypad_scan_task, "keypad_task", 4096, NULL, 6, NULL);
xTaskCreate(door_state_task, "state_task", 4096, NULL, 5, NULL);
......
......@@ -2,68 +2,71 @@
#include <stdint.h>
#include "config.h"
#include "app/latch.h"
#include "app/list.h"
#include "app/event.h"
#include "connectors/rtos.h"
#include "connectors/gpio.h"
#define LATCH_HANDLE_LIST_WAIT_MS 50
static mutex_handle_t latch_handle_list_guard;
static door_list_node_t latch_handle_list_head;
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
//#define LATCH_HANDLE_LIST_WAIT_MS 50
//static mutex_handle_t latch_handle_list_guard;
//static door_list_node_t latch_handle_list_head;
static bool done;
door_latch_event_handle_t door_latch_register_watch(door_latch_event_cb cb)
{
door_list_node_t handle = NULL;
BEGIN_PROTECT_RESOURCE(latch_handle_list_guard, LATCH_HANDLE_LIST_WAIT_MS);
handle = door_list_add(&latch_handle_list_head, &cb, sizeof(door_latch_event_cb));
END_PROTECT_RESOURCE(latch_handle_list_guard);
return handle;
}
void door_latch_unregister_watch(door_latch_event_handle_t handle)
{
BEGIN_PROTECT_RESOURCE(latch_handle_list_guard, LATCH_HANDLE_LIST_WAIT_MS);
door_list_remove(&latch_handle_list_head, handle);
END_PROTECT_RESOURCE(latch_handle_list_guard);
}
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
//door_latch_event_handle_t door_latch_register_watch(door_latch_event_cb cb)
//{
// door_list_node_t handle = NULL;
// BEGIN_PROTECT_RESOURCE(latch_handle_list_guard, LATCH_HANDLE_LIST_WAIT_MS);
// handle = door_list_add(&latch_handle_list_head, &cb, sizeof(door_latch_event_cb));
// END_PROTECT_RESOURCE(latch_handle_list_guard);
// return handle;
//}
//
//void door_latch_unregister_watch(door_latch_event_handle_t handle)
//{
// BEGIN_PROTECT_RESOURCE(latch_handle_list_guard, LATCH_HANDLE_LIST_WAIT_MS);
// door_list_remove(&latch_handle_list_head, handle);
// END_PROTECT_RESOURCE(latch_handle_list_guard);
//}
void door_latch_watch_task(void* pvParameters)
{
(void)pvParameters;
door_latch_initialize();
uint64_t time_counter = 0;
door_latch_state_t prev_state = DOOR_LATCH_CLOSED;
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
// uint64_t time_counter = 0;
// door_latch_state_t prev_state = DOOR_LATCH_CLOSED;
do
{
door_latch_state_t next_state;
// door_latch_state_t next_state;
door_rtos_task_delay(LATCH_CHECK_PERIOD_MS);
++time_counter;
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
// ++time_counter;
if ((next_state = (door_latch_state_t)door_gpio_get_input_pin(DOOR_LATCH_PIN)))
// if ((next_state = (door_latch_state_t)door_gpio_get_input_pin(DOOR_LATCH_PIN)) == DOOR_LATCH_OPENED)
if ((door_latch_state_t)door_gpio_get_input_pin(DOOR_LATCH_PIN) == DOOR_LATCH_OPENED)
door_rtos_event_set(DOOR_LATCH_EVENT);
else
door_rtos_event_clear(DOOR_LATCH_EVENT);
// We have changed states!
if (next_state != prev_state)
{
BEGIN_PROTECT_RESOURCE(latch_handle_list_guard, LATCH_HANDLE_LIST_WAIT_MS);
door_list_node_t tmp = latch_handle_list_head;
while (tmp)
{
door_latch_event_cb cb = *(door_latch_event_cb*)tmp->data;
cb(next_state, time_counter);
tmp = tmp->next;
}
END_PROTECT_RESOURCE(latch_handle_list_guard);
time_counter = 0;
}
prev_state = next_state;
// if (next_state != prev_state)
// {
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
// BEGIN_PROTECT_RESOURCE(latch_handle_list_guard, LATCH_HANDLE_LIST_WAIT_MS);
// door_list_node_t tmp = latch_handle_list_head;
// while (tmp)
// {
// door_latch_event_cb cb = *(door_latch_event_cb*)tmp->data;
// cb(next_state, time_counter);
// tmp = tmp->next;
// }
// END_PROTECT_RESOURCE(latch_handle_list_guard);
// time_counter = 0;
// }
//
// prev_state = next_state;
} while (!done);
}
......@@ -74,7 +77,8 @@ void door_latch_stop(void)
void door_latch_initialize(void)
{
if (!latch_handle_list_guard)
latch_handle_list_guard = door_rtos_mutex_create();
/* UNCOMMENT TO ENABLE LATCH CALLBACK FEATURE */
// if (!latch_handle_list_guard)
// latch_handle_list_guard = door_rtos_mutex_create();
door_gpio_configure_input_pins_pull_down(PIN_MASK(DOOR_LATCH_PIN));
}
#include <stddef.h>
#include "config.h"
#include "app/lock.h"
#include "app/latch.h"
#include "app/event.h"
#include "connectors/rtos.h"
#include "connectors/gpio.h"
#include "config.h"
#define DOOR_UNLOCK_LEVEL DOOR_GPIO_HIGH
#define DOOR_LOCK_LEVEL DOOR_GPIO_LOW
......@@ -28,10 +30,11 @@ void door_lock_task(void* pvParameters)
do
{
notify_value = door_rtos_notify_wait_forever();
if (notify_value & UNLOCK_DOOR)
if (notify_value & UNLOCK_DOOR && !door_rtos_event_get(DOOR_LATCH_EVENT))
{
door_gpio_set_output_pin(DOOR_LOCK_PIN, DOOR_UNLOCK_LEVEL);
door_rtos_task_delay(DOOR_OPEN_LENGTH_MS);
// Stop it early if the door opens.
door_rtos_event_wait_ms(DOOR_LATCH_EVENT, DOOR_OPEN_LENGTH_MS);
door_gpio_set_output_pin(DOOR_LOCK_PIN, DOOR_LOCK_LEVEL);
}
} while (!(notify_value & QUIT_TASK));
......
#include <catch2/catch.hpp>
#include "test_types.h"
#include "app/event.h"
#include "app/latch.h"
TEST_CASE("the latch does latchy thingies and sees when its open/closed", "[door_latch]")
{
Hooks::gpio = std::make_unique<Hooks::GPIO>();
Hooks::rtos = std::make_unique<Hooks::RTOS>();
door_latch_initialize();
door_latch_stop();
SECTION("latch sets event if door is open")
{
Hooks::gpio->get_pin_hook = [&](uint32_t pin) -> bool
{
return true;
};
REQUIRE_FALSE(door_rtos_event_get(DOOR_LATCH_EVENT));
door_latch_watch_task(nullptr);
REQUIRE(door_rtos_event_get(DOOR_LATCH_EVENT));
}
SECTION("latch clears event if door is closed")
{
Hooks::gpio->get_pin_hook = [&](uint32_t pin) -> bool
{
return false;
};
door_rtos_event_set(DOOR_LATCH_EVENT);
door_latch_watch_task(nullptr);
REQUIRE_FALSE(door_rtos_event_get(DOOR_LATCH_EVENT));
}
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ TEST_CASE("door controller door lock module unlocks", "[door_lock]")
Hooks::rtos->notify_wait_forever_hook = [&]() -> uint32_t
{
return notify_return;
return notify_return;
};
SECTION("lock sets up pin")
......@@ -32,9 +32,10 @@ TEST_CASE("door controller door lock module unlocks", "[door_lock]")
{
uint32_t delay_time = 0;
Hooks::rtos->delay_task_hook = [&](uint32_t ms)
Hooks::rtos->event_wait_ms_hook = [&](unsigned int event, uint32_t ms) -> bool
{
delay_time = ms;
delay_time = ms;
return false;
};
door_lock_task(nullptr);
......@@ -46,7 +47,7 @@ TEST_CASE("door controller door lock module unlocks", "[door_lock]")
unsigned set_pin = 0;
Hooks::gpio->set_pin_hook = [&](uint32_t pin, unsigned level)
{
set_pin = pin;
set_pin = pin;
};
door_lock_task(nullptr);
REQUIRE(set_pin == DOOR_LOCK_PIN);
......@@ -69,14 +70,43 @@ TEST_CASE("door controller door lock module unlocks", "[door_lock]")
bool notified = false;
Hooks::rtos->task_get_current_handle_hook = []()
{
return nullptr;
return nullptr;
};
Hooks::rtos->notify_task_hook = [&](task_handle_t task, uint32_t val)
{
notified = true;
notified = true;
};
door_lock_task(nullptr);
door_lock_open();
REQUIRE(notified == 0);
}
SECTION("lock stops open if door opens")
{
bool wait_called = false;
Hooks::rtos->event_wait_ms_hook = [&](unsigned int event, uint32_t ms) -> bool
{
REQUIRE(event == DOOR_LATCH_EVENT);
wait_called = true;
return true;
};
door_lock_task(nullptr);
REQUIRE(wait_called);
}
SECTION("lock won't open if door is already open")
{
Hooks::rtos->event_get_hook = [&](unsigned int event) -> bool
{
return event == DOOR_LATCH_EVENT;
};
Hooks::gpio->set_pin_hook = [&](uint32_t pin, unsigned int level)
{
// fail the test if we get here
REQUIRE(false);
};
door_lock_task(nullptr);
REQUIRE(true);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment