/**
* ECE 315 Computer Interfacing
*
* @file main.c
* @details A simple FreeRTOS template to start projects.
* A producer-consumer task pair blinks the built-in LED.
* @author Steven Knudsen, CCID knud
* @copyright 2025, University of Alberta
* @version 1.0
* @licence MIT
*/
#include "main.h"
#include "hardware/adc.h"
#include "hardware/spi.h"
/**
* uncomment to enable the blocking task
*/
//#define WITH_BLOCKING 1
/*
* GLOBALS
*/
// This is the inter-task queue
volatile QueueHandle_t queue = NULL;
// Set a delay time of exactly 500ms
const TickType_t ms_delay = 500 / portTICK_PERIOD_MS;
// Our tasks
TaskHandle_t pico_adc_task_handle = NULL;
TaskHandle_t pico_spi_task_handle = NULL;
TaskHandle_t blocking_task_handle = NULL;
/*
* FUNCTIONS
*/
/**
* @brief Return number of milliseconds since program start
*/
uint64_t get_ms_freertos(){
return xTaskGetTickCount()/portTICK_PERIOD_MS;
}
/**
* @brief Block to show preemption
*/
void blocking_task(void* unused_arg) {
while (true) {
printf("%-9llums blocking task\n",get_ms_freertos());
vTaskDelay(ms_delay);
}
}
void adc_task(void* unused_arg){
adc_init();
adc_gpio_init(26);
while(1){
adc_select_input(0);
uint32_t adcVal = adc_read();
printf("ADC Val: %d\n", adcVal);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
void spi_task(void* unused_arg){
const char* message = "Hello World!\n\0";
spi_init(spi_default, 500*1000);
gpio_set_function(19, GPIO_FUNC_SPI);
gpio_set_function(18, GPIO_FUNC_SPI);
gpio_init(16);
gpio_set_dir(16, GPIO_OUT);
gpio_put(16, 1);
// while(1){
// vTaskDelay(1000 / portTICK_PERIOD_MS);
// }
while(1){
gpio_put(16, 0);
spi_write_blocking(spi_default, message, strlen(message));
gpio_put(16, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
/*
* RUNTIME START
*/
int main() {
// Enable STDIO
stdio_init_all();
BaseType_t adc_status = xTaskCreate(adc_task,
"PICO_ADC_TASK",
1024,
NULL,
1,
&pico_adc_task_handle);
BaseType_t spi_status = xTaskCreate(spi_task,
"PICO_SPI_TASK",
1024,
NULL,
1,
&pico_spi_task_handle);
#if WITH_BLOCKING
BaseType_t block_status = xTaskCreate(blocking_task,
"BLOCKING_TASK",
1024,
NULL,
1,
&blocking_task_handle);
#else
BaseType_t block_status = pdPASS;
#endif
// Set up the event queue
queue = xQueueCreate(4, sizeof(uint8_t));
// Start the FreeRTOS scheduler
// Only proceed with valid tasks
vTaskStartScheduler();
// We should never get here, but just in case...
while(true) {
// NOP
}
}