//#define PICO #ifdef PICO #include #include #include "FreeRTOS.h" #include "task.h" #else #include #include #include #include #include #define PICO_DEFAULT_LED_PIN 0 #define GPIO_OUT 1 #define GPIO_IN 0 #endif #include #include "log.h" #include "jobs.h" #include "gpio.h" #include "utils.h" #define ALARM_BASE_FREQ 1500 // auditive frequency human range: [20; 20000] hertz #define ALARM_PERIOD_MS 200 #define PI 3.14 /** * Oscillator for passive buzzer hardware. * * It generates desired `freq_hz` for `duration_ms`. * * NOTE: `sleep_us` method does not impact FreeRTOS engine * since, the scheduler started on two cores (RP2350). The behavior may differs * on one core. Update the FreeRTOS tick freq and implement `pdUS_TO_TICKS` if needed or, * run the alarm in dedicated core see: `xTaskCreateAffinitySet`. */ void gen_freq(gpio* g, size_t freq_hz, size_t duration_ms) { if (!freq_hz) { gpio_set_state(g, 0); return; } float period = (1.0 / freq_hz) * 1000000; // signal period in micro seconds size_t duty_period = period / 2; // working period = period / 2 size_t nb_period = duration_ms * 1000 / period; // number of period to play debug("freq_hz = (%ld), period_us = (%.2f), duty_period_us = (%ld), nb_period = (%ld)", freq_hz, period, duty_period, nb_period); for (size_t i = 0; i < nb_period; i++) { gpio_set_state(g, true); _sleep_us(duty_period); gpio_set_state(g, false); _sleep_us(duty_period); } } void run_alarm(void *const params) { AppState* as = (AppState* ) params; for(;;) { if (lock(as) != 0) fatal(stop_app_fallback, "unable to lock the app state"); uint16_t freq = as->freq_multiplicator * 500 + ALARM_BASE_FREQ; if (release(as) != 0) fatal(stop_app_fallback, "unable to release the app state"); #ifdef PICO gpio_set_level(GPIOS[4], as->freq_multiplicator * DEFAULT_WRAP_LEVEL); #endif debug("running alarm..."); float sin_val; int tone_val; const size_t duration_ms = ALARM_PERIOD_MS / 36; for (size_t i = 0; i < 360; i+=10) { sin_val = sinf(i * (PI / 180)); tone_val = freq + sin_val * (freq / 10); gen_freq(GPIOS[2], tone_val, duration_ms); } } } int init_check_adc_value(AppState* as) { #ifdef PICO BaseType_t res = xTaskCreateAffinitySet(check_acd_value, "check_adc_value", configMINIMAL_STACK_SIZE, (void *const)as, configMAX_PRIORITIES - 1U, 1 << 0, NULL); if (res != pdPASS) return -1; return 0; #else pthread_t task; if (pthread_create(&task, NULL, check_acd_value, as) != 0) { return -1; } return 0; #endif } // Initialize the main FreeRTOS task. int init_rtos_main(TaskParam *params) { #ifdef PICO BaseType_t res = xTaskCreateAffinitySet(check_btn_state, "main", configMINIMAL_STACK_SIZE, (void *const)params, configMAX_PRIORITIES - 1U, 1 << 0, NULL); if (res != pdPASS) return -1; return 0; #endif } /** * A program to run alarm on button pushed. * * To activate the alarm, push the button. Same for desactivation. * The alarm is launched in a separate task and controlled by * the main task (which holds the push button logic). * * Hardware: * - 1x Passive Buzzer * - 1x Push button * - 1 NPN transistor for signal amplification * - 1x 1k ohm resistor (NPN collector) * - 2x 10k ohm resistor * * You can run the application in "DEBUG" mode using: * `make run-debug name=buzzer` * The FreeRTOS engine is replaced by threads. * * A variant to play with the frequency can be done adding a * potentiometer and set `check_adc` to true. See README.md for details. * */ int main() { init_gpio(); bool check_adc = false; AppState as; if (init_app_state(&as) != 0) fatal(stop_app_fallback, "unable to initilize the application"); TaskParam params = (TaskParam) { .s = &as, .f = run_alarm, }; // launch the check of the ADC value reveived by the potentiometer if (check_adc) if (init_check_adc_value(&as) != 0) fatal(stop_app_fallback, "unable to launch check adc value task"); #ifdef PICO if (init_rtos_main(¶ms) != 0) fatal(stop_app_fallback, "unable to launch to FreeRTOS main task"); info("application init with success"); vTaskStartScheduler(); #else info("application init with success"); check_btn_state(¶ms); #endif fatal(stop_app_fallback, "unable to launch the application"); }