From 2b34f8c8563d0b3db6ac0dc5f8f48f6df314ef92 Mon Sep 17 00:00:00 2001 From: Devoalda Date: Mon, 23 Oct 2023 21:22:12 +0800 Subject: [PATCH] feature(Line sensor Interrupts): Added Edge Interrupt logic with debounce algorithm --- frtos/line_sensor/line_sensor.h | 144 ++++++++++++++------------- frtos/line_sensor/line_sensor_init.h | 62 +++++++++++- frtos/line_sensor/line_sensor_test.c | 46 +++++---- 3 files changed, 163 insertions(+), 89 deletions(-) diff --git a/frtos/line_sensor/line_sensor.h b/frtos/line_sensor/line_sensor.h index bfdb9e8..23c30e0 100644 --- a/frtos/line_sensor/line_sensor.h +++ b/frtos/line_sensor/line_sensor.h @@ -20,14 +20,19 @@ monitor_left_sensor_task(__unused void *params) { { if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE) { - // Get Current State - state_t state = gpio_get(LEFT_SENSOR_PIN); - - xMessageBufferSend(left_sensor_msg_buffer, - &state, - sizeof(state_t), - 0); + if (left_sensor_triggered == pdTRUE) + { + printf("left sensor triggered\n"); + // Get Current State + state_t state = gpio_get(LEFT_SENSOR_PIN); + xMessageBufferSend(left_sensor_msg_buffer, + &state, + sizeof(state_t), + 0); + // Reset the flag + left_sensor_triggered = pdFALSE; + } } } } @@ -41,22 +46,27 @@ monitor_left_sensor_task(__unused void *params) { * @param params */ void -monitor_right_sensor_task(__unused void *params) { - for (;;) - { - if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) - { - // Get Current State - state_t state = gpio_get(RIGHT_SENSOR_PIN); +monitor_right_sensor_task(void *params) { + for (;;) { + if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) { + // Check the flag or receive the message + if (right_sensor_triggered == pdTRUE) { + printf("right sensor triggered\n"); + // Get Current State + state_t state = gpio_get(RIGHT_SENSOR_PIN); - xMessageBufferSend(right_sensor_msg_buffer, - &state, - sizeof(state_t), - 0); + xMessageBufferSend(right_sensor_msg_buffer, + &state, + sizeof(state_t), + 0); + // Reset the flag + right_sensor_triggered = pdFALSE; + } } } } + /** * @brief Monitor the direction and Oritentation of the car * @@ -83,55 +93,55 @@ monitor_direction_task(__unused void *params) { sizeof(state_t), portMAX_DELAY); - g_car_state.current_direction = (left_state << 1) | right_state; +// g_car_state.current_direction = (left_state << 1) | right_state; - switch (g_car_state.current_direction) - { - case FORWARD: - break; - case RIGHT: - g_car_state.orientation = (g_car_state.orientation + 1) & 0x03; - break; - case LEFT: - g_car_state.orientation = (g_car_state.orientation - 1) & 0x03; - break; - default: - break; - } - - switch (g_car_state.current_direction) - { - case FORWARD: - printf("Direction: Forward\n"); - break; - case RIGHT: - printf("Direction: Right\n"); - break; - case LEFT: - printf("Direction: Left\n"); - break; - default: - printf("Direction: Error\n"); - break; - } - - switch (g_car_state.orientation) - { - case NORTH: - printf("Orientation: North\n"); - break; - case EAST: - printf("Orientation: East\n"); - break; - case SOUTH: - printf("Orientation: South\n"); - break; - case WEST: - printf("Orientation: West\n"); - break; - default: - printf("Orientation: Error\n"); - break; - } +// switch (g_car_state.current_direction) +// { +// case FORWARD: +// break; +// case RIGHT: +// g_car_state.orientation = (g_car_state.orientation + 1) & 0x03; +// break; +// case LEFT: +// g_car_state.orientation = (g_car_state.orientation - 1) & 0x03; +// break; +// default: +// break; +// } +// +// switch (g_car_state.current_direction) +// { +// case FORWARD: +// printf("Direction: Forward\n"); +// break; +// case RIGHT: +// printf("Direction: Right\n"); +// break; +// case LEFT: +// printf("Direction: Left\n"); +// break; +// default: +// printf("Direction: Error\n"); +// break; +// } +// +// switch (g_car_state.orientation) +// { +// case NORTH: +// printf("Orientation: North\n"); +// break; +// case EAST: +// printf("Orientation: East\n"); +// break; +// case SOUTH: +// printf("Orientation: South\n"); +// break; +// case WEST: +// printf("Orientation: West\n"); +// break; +// default: +// printf("Orientation: Error\n"); +// break; +// } } } \ No newline at end of file diff --git a/frtos/line_sensor/line_sensor_init.h b/frtos/line_sensor/line_sensor_init.h index 775ba9d..ecfb4ec 100644 --- a/frtos/line_sensor/line_sensor_init.h +++ b/frtos/line_sensor/line_sensor_init.h @@ -19,6 +19,11 @@ #include "line_sensor_config.h" +#define DEBOUNCE_DELAY_MS 100 + +static TickType_t lastEdgeTimeLeft = 0; +static TickType_t lastEdgeTimeRight = 0; + typedef enum { // Unused, useful for readability LINE_DETECTED = 0, LINE_NOT_DETECTED = 1, @@ -53,6 +58,9 @@ SemaphoreHandle_t g_right_sensor_sem = NULL; static MessageBufferHandle_t left_sensor_msg_buffer; // Left Sensor Buffer static MessageBufferHandle_t right_sensor_msg_buffer; // Right Sensor Buffer +static volatile BaseType_t right_sensor_triggered = pdFALSE; +static volatile BaseType_t left_sensor_triggered = pdFALSE; + // Car State Struct static car_state_t g_car_state; @@ -72,16 +80,16 @@ static car_state_t initialize_car_state() { */ static inline void line_sensor_setup() { - g_left_sensor_sem = xSemaphoreCreateBinary(); - g_right_sensor_sem = xSemaphoreCreateBinary(); + g_left_sensor_sem = xSemaphoreCreateBinary(); + g_right_sensor_sem = xSemaphoreCreateBinary(); - uint mask = (1 << LEFT_SENSOR_PIN) | (1 << RIGHT_SENSOR_PIN); + uint mask = (1 << LEFT_SENSOR_PIN) | (1 << RIGHT_SENSOR_PIN); // Initialise 2 GPIO pins and set them to input gpio_init_mask(mask); gpio_set_dir_in_masked(mask); - left_sensor_msg_buffer = xMessageBufferCreate(30); + left_sensor_msg_buffer = xMessageBufferCreate(30); right_sensor_msg_buffer = xMessageBufferCreate(30); } @@ -115,4 +123,50 @@ bool h_right_sensor_timer_handler(repeating_timer_t *repeatingTimer) { return true; } + +void h_line_sensor_handler(void) { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + TickType_t currentTicks = xTaskGetTickCount(); + printf("Interrupt triggered\n"); + + if (gpio_get_irq_event_mask(LEFT_SENSOR_PIN) & GPIO_IRQ_EDGE_FALL) + { + if ((currentTicks - lastEdgeTimeLeft) >= + pdMS_TO_TICKS(DEBOUNCE_DELAY_MS)) + { + lastEdgeTimeLeft = currentTicks; + gpio_acknowledge_irq(LEFT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL); + + left_sensor_triggered = pdTRUE; + xSemaphoreGiveFromISR(g_left_sensor_sem, &xHigherPriorityTaskWoken); + } + else + { + // Reset the timer to the currentTicks if the edge is ignored + lastEdgeTimeLeft = currentTicks; + } + } + + if (gpio_get_irq_event_mask(RIGHT_SENSOR_PIN) & GPIO_IRQ_EDGE_FALL) + { + if ((currentTicks - lastEdgeTimeRight) >= + pdMS_TO_TICKS(DEBOUNCE_DELAY_MS)) + { + lastEdgeTimeRight = currentTicks; + gpio_acknowledge_irq(RIGHT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL); + // Set the flag to notify the task + right_sensor_triggered = pdTRUE; + xSemaphoreGiveFromISR(g_right_sensor_sem, + &xHigherPriorityTaskWoken); + } + else + { + // Reset the timer to the currentTicks if the edge is ignored + lastEdgeTimeRight = currentTicks; + } + } + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + #endif /* LINE_SENSOR_INIT_H */ diff --git a/frtos/line_sensor/line_sensor_test.c b/frtos/line_sensor/line_sensor_test.c index ecfc0f2..44750da 100644 --- a/frtos/line_sensor/line_sensor_test.c +++ b/frtos/line_sensor/line_sensor_test.c @@ -9,17 +9,27 @@ void launch() { - struct repeating_timer g_left_sensor_timer; - add_repeating_timer_ms(LINE_SENSOR_READ_DELAY, - h_left_sensor_timer_handler, - NULL, - &g_left_sensor_timer); + // isr to detect left line sensor + gpio_set_irq_enabled(LEFT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL, true); + gpio_add_raw_irq_handler(LEFT_SENSOR_PIN, h_line_sensor_handler); - struct repeating_timer g_right_sensor_timer; - add_repeating_timer_ms(LINE_SENSOR_READ_DELAY, - h_right_sensor_timer_handler, - NULL, - &g_right_sensor_timer); + // isr to detect right line sensor + gpio_set_irq_enabled(RIGHT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL, true); + gpio_add_raw_irq_handler(RIGHT_SENSOR_PIN, h_line_sensor_handler); + + irq_set_enabled(IO_IRQ_BANK0, true); + +// struct repeating_timer g_left_sensor_timer; +// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY, +// h_left_sensor_timer_handler, +// NULL, +// &g_left_sensor_timer); +// +// struct repeating_timer g_right_sensor_timer; +// add_repeating_timer_ms(LINE_SENSOR_READ_DELAY, +// h_right_sensor_timer_handler, +// NULL, +// &g_right_sensor_timer); TaskHandle_t h_monitor_left_sensor_task; xTaskCreate(monitor_left_sensor_task, @@ -37,13 +47,13 @@ launch() READ_RIGHT_SENSOR_PRIO, &h_monitor_right_sensor_task); - TaskHandle_t h_monitor_direction_task; - xTaskCreate(monitor_direction_task, - "Monitor Direction Task", - configMINIMAL_STACK_SIZE, - NULL, - DIRECTION_TASK_PRIORITY, - &h_monitor_direction_task); +// TaskHandle_t h_monitor_direction_task; +// xTaskCreate(monitor_direction_task, +// "Monitor Direction Task", +// configMINIMAL_STACK_SIZE, +// NULL, +// DIRECTION_TASK_PRIORITY, +// &h_monitor_direction_task); vTaskStartScheduler(); } @@ -53,7 +63,7 @@ main (void) { stdio_usb_init(); - sleep_ms(2000); +// sleep_ms(2000); printf("Test started!\n"); line_sensor_setup();