Skip to content

Commit 79b5bd8

Browse files
committed
add example blinkys
1 parent b89e1d4 commit 79b5bd8

File tree

14 files changed

+2428
-192
lines changed

14 files changed

+2428
-192
lines changed

.gitmodules

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
[submodule "src/third_party/canlib"]
22
path = src/third_party/canlib
3-
url = https://github.com/waterloo-rocketry/canlib
3+
url = https://github.com/waterloo-rocketry/canlib.git
44
[submodule "src/third_party/rocketlib"]
55
path = src/third_party/rocketlib
6-
url = https://github.com/waterloo-rocketry/rocketlib
7-
[submodule "tests/mocks/fff"]
8-
path = tests/mocks/fff
9-
url = https://github.com/meekrosoft/fff.git
10-
[submodule "tests/external/googletest"]
11-
path = tests/external/googletest
12-
url = https://github.com/google/googletest.git
13-
[submodule "src/third_party/CMSIS-DSP"]
14-
path = src/third_party/CMSIS-DSP
15-
url = https://github.com/ARM-software/CMSIS-DSP
6+
url = https://github.com/waterloo-rocketry/rocketlib.git

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"files.associations": {
33
"*.csv": "csv",
44
"freertos.h": "c",
5-
"semphr.h": "c"
5+
"semphr.h": "c",
6+
"init.h": "c"
67
}
78
}

README.md

Lines changed: 149 additions & 107 deletions
Large diffs are not rendered by default.

Src/application/init/init.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "stm32h7xx_hal.h"
2+
#include "FreeRTOS.h"
3+
#include "task.h"
4+
#include "init.h"
5+
#include "gpio.h"
6+
#include "drivers/gpio/gpio.h"
7+
8+
// add more task handles as needed
9+
TaskHandle_t blinky_task_handle = NULL;
10+
11+
// add task priorities as needed
12+
const uint32_t blinky_task_priority = tskIDLE_PRIORITY + 1;
13+
14+
// example blinky task
15+
static void blinky_task(void *pvParameters)
16+
{
17+
(void)pvParameters;
18+
19+
for (;;)
20+
{
21+
gpio_toggle(GPIO_PIN_RED_LED, 5);
22+
vTaskDelay(pdMS_TO_TICKS(500));
23+
}
24+
}
25+
26+
// Init all modules and spawn all tasks here
27+
w_status_t system_init(void)
28+
{
29+
w_status_t status = W_SUCCESS;
30+
31+
// initialize more modules as needed
32+
status = gpio_init();
33+
34+
if (status != W_SUCCESS)
35+
{
36+
return status;
37+
}
38+
39+
// create more tasks as needed
40+
BaseType_t tasks_created = xTaskCreate(
41+
blinky_task,
42+
"blinky",
43+
configMINIMAL_STACK_SIZE,
44+
NULL,
45+
blinky_task_priority,
46+
&blinky_task_handle);
47+
48+
if (tasks_created != pdPASS)
49+
{
50+
return W_OVERFLOW;
51+
}
52+
53+
return W_SUCCESS;
54+
}

Src/application/init/init.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef INIT_H
2+
#define INIT_H
3+
4+
#include "FreeRTOS.h"
5+
#include "main.h" // For HAL handle declarations
6+
#include "rocketlib/include/common.h"
7+
#include "task.h"
8+
9+
// Maximum number of initialization retries before giving up
10+
#define MAX_INIT_RETRIES 1
11+
12+
// Delay between initialization retries in milliseconds
13+
#define INIT_RETRY_DELAY_MS 1000
14+
15+
// Task handles - defined in init.c
16+
extern TaskHandle_t log_task_handle;
17+
extern TaskHandle_t estimator_task_handle;
18+
extern TaskHandle_t can_handler_handle_tx;
19+
extern TaskHandle_t can_handler_handle_rx;
20+
extern TaskHandle_t health_checks_task_handle;
21+
extern TaskHandle_t controller_task_handle;
22+
extern TaskHandle_t flight_phase_task_handle;
23+
extern TaskHandle_t imu_handler_task_handle;
24+
extern TaskHandle_t movella_task_handle;
25+
26+
// Task priorities
27+
extern const uint32_t flight_phase_task_priority;
28+
extern const uint32_t log_task_priority;
29+
extern const uint32_t estimator_task_priority;
30+
extern const uint32_t controller_task_priority;
31+
extern const uint32_t can_handler_rx_priority;
32+
extern const uint32_t can_handler_tx_priority;
33+
extern const uint32_t health_checks_task_priority;
34+
extern const uint32_t imu_handler_task_priority;
35+
extern const uint32_t movella_task_priority;
36+
37+
// Helper function to retry an initialization function
38+
w_status_t init_with_retry(w_status_t (*init_fn)(void));
39+
w_status_t init_with_retry_param(w_status_t (*init_fn)(void *), void *param);
40+
41+
// Main initialization function that sets up everything
42+
w_status_t system_init(void);
43+
44+
#endif // INIT_H

Src/drivers/gpio/gpio.c

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/**
2+
* GPIO module
3+
* Driver for GPIO pins
4+
*/
5+
#include <stdbool.h>
6+
7+
#include "stm32h7xx_hal.h"
8+
9+
#include "FreeRTOS.h"
10+
#include "semphr.h"
11+
12+
#include "drivers/gpio/gpio.h"
13+
14+
// Private --------------------------------------------------------------------
15+
16+
/**
17+
* Private status trackers
18+
*/
19+
typedef struct
20+
{
21+
bool is_init; // Whether module is initialized
22+
uint32_t accesses; // # of successful r/w
23+
uint32_t access_fails; // # of failed r/w
24+
bool err; // Whether module is currently in err state for any reason
25+
} gpio_module_status_t;
26+
27+
static gpio_module_status_t gpio_status = {0};
28+
29+
/**
30+
* Private gpio pin data for 1 pin
31+
*/
32+
typedef struct
33+
{
34+
GPIO_TypeDef *port; // HAL GPIO port
35+
uint16_t pin; // HAL GPIO pin bit mask
36+
SemaphoreHandle_t access_mutex; // access mutex
37+
} gpio_pin_data_t;
38+
39+
/**
40+
* Map gpio pins enums to their hardware data
41+
*/
42+
static gpio_pin_data_t gpio_map[GPIO_PIN_COUNT] = {
43+
[GPIO_PIN_RED_LED] = {.port = GPIOE, .pin = GPIO_PIN_9, .access_mutex = NULL},
44+
[GPIO_PIN_GREEN_LED] = {.port = GPIOE, .pin = GPIO_PIN_10, .access_mutex = NULL},
45+
[GPIO_PIN_BLUE_LED] = {.port = GPIOE, .pin = GPIO_PIN_11, .access_mutex = NULL},
46+
};
47+
48+
// Public ---------------------------------------------------------------------
49+
50+
/**
51+
* Initialize gpio module. Can be run before scheduler start
52+
*/
53+
w_status_t gpio_init()
54+
{
55+
w_status_t status = W_SUCCESS;
56+
57+
gpio_status.is_init = false;
58+
gpio_status.accesses = 0;
59+
gpio_status.access_fails = 0;
60+
gpio_status.err = false;
61+
62+
// Initialize the access mutex for each pin
63+
for (int i = 0; i < GPIO_PIN_COUNT; i++)
64+
{
65+
gpio_map[i].access_mutex = xSemaphoreCreateMutex();
66+
if (gpio_map[i].access_mutex == NULL)
67+
{
68+
gpio_status.err = true;
69+
// log_text(10, "gpio", "initfail %d", i);
70+
status = W_FAILURE;
71+
}
72+
}
73+
74+
if (status == W_SUCCESS)
75+
{
76+
gpio_status.is_init = true;
77+
}
78+
else
79+
{
80+
}
81+
82+
return status;
83+
}
84+
85+
/**
86+
* Read the current level of `pin` into `level`.
87+
* Block for up to `timeout` ms.
88+
*/
89+
w_status_t gpio_read(gpio_pin_t pin, gpio_level_t *level, uint32_t timeout)
90+
{
91+
if (pin >= GPIO_PIN_COUNT || level == NULL)
92+
{
93+
gpio_status.access_fails++;
94+
return W_INVALID_PARAM;
95+
}
96+
97+
if (xSemaphoreTake(gpio_map[pin].access_mutex, pdMS_TO_TICKS(timeout)) == pdTRUE)
98+
{
99+
GPIO_PinState state = HAL_GPIO_ReadPin(gpio_map[pin].port, gpio_map[pin].pin);
100+
*level = (state == GPIO_PIN_SET) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
101+
102+
gpio_status.accesses++;
103+
xSemaphoreGive(gpio_map[pin].access_mutex);
104+
105+
return W_SUCCESS;
106+
}
107+
else
108+
{
109+
gpio_status.access_fails++;
110+
return W_IO_TIMEOUT;
111+
}
112+
}
113+
114+
/**
115+
* Set `pin` to `level`. Block for up to `timeout` ms.
116+
*/
117+
w_status_t gpio_write(gpio_pin_t pin, gpio_level_t level, uint32_t timeout)
118+
{
119+
if (pin >= GPIO_PIN_COUNT)
120+
{
121+
gpio_status.access_fails++;
122+
return W_INVALID_PARAM;
123+
}
124+
125+
if (xSemaphoreTake(gpio_map[pin].access_mutex, pdMS_TO_TICKS(timeout)) == pdTRUE)
126+
{
127+
HAL_GPIO_WritePin(
128+
gpio_map[pin].port,
129+
gpio_map[pin].pin,
130+
(level == GPIO_LEVEL_HIGH) ? GPIO_PIN_SET : GPIO_PIN_RESET);
131+
gpio_status.accesses++;
132+
133+
xSemaphoreGive(gpio_map[pin].access_mutex);
134+
135+
return W_SUCCESS;
136+
}
137+
else
138+
{
139+
gpio_status.access_fails++;
140+
return W_IO_TIMEOUT;
141+
}
142+
}
143+
144+
/**
145+
* Toggle `pin` between high/low from its current level.
146+
* Block for up to `timeout` ms.
147+
*/
148+
w_status_t gpio_toggle(gpio_pin_t pin, uint32_t timeout)
149+
{
150+
if (pin >= GPIO_PIN_COUNT)
151+
{
152+
gpio_status.access_fails++;
153+
return W_INVALID_PARAM;
154+
}
155+
156+
if (xSemaphoreTake(gpio_map[pin].access_mutex, pdMS_TO_TICKS(timeout)) == pdTRUE)
157+
{
158+
HAL_GPIO_TogglePin(gpio_map[pin].port, gpio_map[pin].pin);
159+
gpio_status.accesses++;
160+
161+
xSemaphoreGive(gpio_map[pin].access_mutex);
162+
163+
return W_SUCCESS;
164+
}
165+
else
166+
{
167+
gpio_status.access_fails++;
168+
return W_IO_TIMEOUT;
169+
}
170+
}
171+
172+
// /**
173+
// * Reports the current status of the GPIO module
174+
// * @return Status code indicating success or failure
175+
// */
176+
// uint32_t gpio_get_status(void) {
177+
// uint32_t status_bitfield = 0;
178+
179+
// // Log operation statistics
180+
// log_text(
181+
// 0,
182+
// "gpio",
183+
// "%s Successful accesses: %lu, Failed accesses: %lu",
184+
// gpio_status.is_init ? "INIT" : "NOT INIT",
185+
// gpio_status.accesses,
186+
// gpio_status.access_fails
187+
// );
188+
189+
// return status_bitfield;
190+
// }

Src/drivers/gpio/gpio.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* GPIO module
3+
* Driver for GPIO pins
4+
*/
5+
#ifndef GPIO_H
6+
#define GPIO_H
7+
8+
#include <stdint.h>
9+
10+
#include "rocketlib/include/common.h"
11+
12+
/**
13+
* Enum representing GPIO pin level
14+
*/
15+
typedef enum
16+
{
17+
GPIO_LEVEL_LOW,
18+
GPIO_LEVEL_HIGH
19+
} gpio_level_t;
20+
21+
/**
22+
* Enum representing a connected GPIO pin
23+
*/
24+
typedef enum
25+
{
26+
GPIO_PIN_RED_LED,
27+
GPIO_PIN_GREEN_LED,
28+
GPIO_PIN_BLUE_LED,
29+
GPIO_PIN_COUNT // Enum max value
30+
} gpio_pin_t;
31+
32+
/**
33+
* Initialize gpio module. Inits status trackers and mutexes
34+
*/
35+
w_status_t gpio_init();
36+
37+
/**
38+
* Read the current level of `pin` into `level`.
39+
* Block for up to `timeout` ms.
40+
*/
41+
w_status_t gpio_read(gpio_pin_t pin, gpio_level_t *level, uint32_t timeout);
42+
43+
/**
44+
* Set `pin` to `level`. Block for up to `timeout` ms.
45+
*/
46+
w_status_t gpio_write(gpio_pin_t pin, gpio_level_t level, uint32_t timeout);
47+
48+
/**
49+
* Toggle `pin` between high/low from its current level.
50+
* Block for up to `timeout` ms.
51+
*/
52+
w_status_t gpio_toggle(gpio_pin_t pin, uint32_t timeout);
53+
54+
/**
55+
* Reports the current status of the GPIO module
56+
* @return CAN board status bitfield
57+
*/
58+
uint32_t gpio_get_status(void);
59+
60+
#endif // GPIO_H

0 commit comments

Comments
 (0)