Merge pull request #5 from Devoalda/main

Line Sensor Edge Interrupt
This commit is contained in:
Richie Wang 2023-10-23 21:24:31 +08:00 committed by GitHub
commit e8621be24b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 163 additions and 89 deletions

View File

@ -20,14 +20,19 @@ monitor_left_sensor_task(__unused void *params) {
{ {
if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE) if (xSemaphoreTake(g_left_sensor_sem, portMAX_DELAY) == pdTRUE)
{ {
// Get Current State if (left_sensor_triggered == pdTRUE)
state_t state = gpio_get(LEFT_SENSOR_PIN); {
printf("left sensor triggered\n");
xMessageBufferSend(left_sensor_msg_buffer, // Get Current State
&state, state_t state = gpio_get(LEFT_SENSOR_PIN);
sizeof(state_t),
0);
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 * @param params
*/ */
void void
monitor_right_sensor_task(__unused void *params) { monitor_right_sensor_task(void *params) {
for (;;) for (;;) {
{ if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) {
if (xSemaphoreTake(g_right_sensor_sem, portMAX_DELAY) == pdTRUE) // Check the flag or receive the message
{ if (right_sensor_triggered == pdTRUE) {
// Get Current State printf("right sensor triggered\n");
state_t state = gpio_get(RIGHT_SENSOR_PIN); // Get Current State
state_t state = gpio_get(RIGHT_SENSOR_PIN);
xMessageBufferSend(right_sensor_msg_buffer, xMessageBufferSend(right_sensor_msg_buffer,
&state, &state,
sizeof(state_t), sizeof(state_t),
0); 0);
// Reset the flag
right_sensor_triggered = pdFALSE;
}
} }
} }
} }
/** /**
* @brief Monitor the direction and Oritentation of the car * @brief Monitor the direction and Oritentation of the car
* *
@ -83,55 +93,55 @@ monitor_direction_task(__unused void *params) {
sizeof(state_t), sizeof(state_t),
portMAX_DELAY); 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) // switch (g_car_state.current_direction)
{ // {
case FORWARD: // case FORWARD:
break; // break;
case RIGHT: // case RIGHT:
g_car_state.orientation = (g_car_state.orientation + 1) & 0x03; // g_car_state.orientation = (g_car_state.orientation + 1) & 0x03;
break; // break;
case LEFT: // case LEFT:
g_car_state.orientation = (g_car_state.orientation - 1) & 0x03; // g_car_state.orientation = (g_car_state.orientation - 1) & 0x03;
break; // break;
default: // default:
break; // break;
} // }
//
switch (g_car_state.current_direction) // switch (g_car_state.current_direction)
{ // {
case FORWARD: // case FORWARD:
printf("Direction: Forward\n"); // printf("Direction: Forward\n");
break; // break;
case RIGHT: // case RIGHT:
printf("Direction: Right\n"); // printf("Direction: Right\n");
break; // break;
case LEFT: // case LEFT:
printf("Direction: Left\n"); // printf("Direction: Left\n");
break; // break;
default: // default:
printf("Direction: Error\n"); // printf("Direction: Error\n");
break; // break;
} // }
//
switch (g_car_state.orientation) // switch (g_car_state.orientation)
{ // {
case NORTH: // case NORTH:
printf("Orientation: North\n"); // printf("Orientation: North\n");
break; // break;
case EAST: // case EAST:
printf("Orientation: East\n"); // printf("Orientation: East\n");
break; // break;
case SOUTH: // case SOUTH:
printf("Orientation: South\n"); // printf("Orientation: South\n");
break; // break;
case WEST: // case WEST:
printf("Orientation: West\n"); // printf("Orientation: West\n");
break; // break;
default: // default:
printf("Orientation: Error\n"); // printf("Orientation: Error\n");
break; // break;
} // }
} }
} }

View File

@ -19,6 +19,11 @@
#include "line_sensor_config.h" #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 typedef enum { // Unused, useful for readability
LINE_DETECTED = 0, LINE_DETECTED = 0,
LINE_NOT_DETECTED = 1, 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 left_sensor_msg_buffer; // Left Sensor Buffer
static MessageBufferHandle_t right_sensor_msg_buffer; // Right 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 // Car State Struct
static car_state_t g_car_state; static car_state_t g_car_state;
@ -72,16 +80,16 @@ static car_state_t initialize_car_state() {
*/ */
static inline void static inline void
line_sensor_setup() { line_sensor_setup() {
g_left_sensor_sem = xSemaphoreCreateBinary(); g_left_sensor_sem = xSemaphoreCreateBinary();
g_right_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 // Initialise 2 GPIO pins and set them to input
gpio_init_mask(mask); gpio_init_mask(mask);
gpio_set_dir_in_masked(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); right_sensor_msg_buffer = xMessageBufferCreate(30);
} }
@ -115,4 +123,50 @@ bool h_right_sensor_timer_handler(repeating_timer_t *repeatingTimer) {
return true; 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 */ #endif /* LINE_SENSOR_INIT_H */

View File

@ -9,17 +9,27 @@
void void
launch() launch()
{ {
struct repeating_timer g_left_sensor_timer; // isr to detect left line sensor
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY, gpio_set_irq_enabled(LEFT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL, true);
h_left_sensor_timer_handler, gpio_add_raw_irq_handler(LEFT_SENSOR_PIN, h_line_sensor_handler);
NULL,
&g_left_sensor_timer);
struct repeating_timer g_right_sensor_timer; // isr to detect right line sensor
add_repeating_timer_ms(LINE_SENSOR_READ_DELAY, gpio_set_irq_enabled(RIGHT_SENSOR_PIN, GPIO_IRQ_EDGE_FALL, true);
h_right_sensor_timer_handler, gpio_add_raw_irq_handler(RIGHT_SENSOR_PIN, h_line_sensor_handler);
NULL,
&g_right_sensor_timer); 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; TaskHandle_t h_monitor_left_sensor_task;
xTaskCreate(monitor_left_sensor_task, xTaskCreate(monitor_left_sensor_task,
@ -37,13 +47,13 @@ launch()
READ_RIGHT_SENSOR_PRIO, READ_RIGHT_SENSOR_PRIO,
&h_monitor_right_sensor_task); &h_monitor_right_sensor_task);
TaskHandle_t h_monitor_direction_task; // TaskHandle_t h_monitor_direction_task;
xTaskCreate(monitor_direction_task, // xTaskCreate(monitor_direction_task,
"Monitor Direction Task", // "Monitor Direction Task",
configMINIMAL_STACK_SIZE, // configMINIMAL_STACK_SIZE,
NULL, // NULL,
DIRECTION_TASK_PRIORITY, // DIRECTION_TASK_PRIORITY,
&h_monitor_direction_task); // &h_monitor_direction_task);
vTaskStartScheduler(); vTaskStartScheduler();
} }
@ -53,7 +63,7 @@ main (void)
{ {
stdio_usb_init(); stdio_usb_init();
sleep_ms(2000); // sleep_ms(2000);
printf("Test started!\n"); printf("Test started!\n");
line_sensor_setup(); line_sensor_setup();