picoco/buzzer/gpio.c
2025-03-05 10:43:11 +01:00

124 lines
2.6 KiB
C

//#define PICO
#ifdef PICO
#include <pico/printf.h>
#include <pico/stdlib.h>
#include <hardware/pwm.h>
#include <hardware/adc.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#define GPIO_OUT 1
#define GPIO_IN 0
static size_t GPIO_INPUT_MOCK_COUNTER = 0;
#endif
#include "gpio.h"
#include "log.h"
void _sleep_ms(size_t value) {
#ifdef PICO
sleep_ms(value);
#else
usleep(value * 1000);
#endif
}
void _sleep_us(size_t value) {
#ifdef PICO
sleep_us(value);
#else
usleep(value);
#endif
}
/**
* Returns a ratio of the ADC value input.
*
* The range of the ADC on Raspberry Pico 2 is 10 bits so the resolution is 1024 (2^10).
*
*/
double gpio_get_adc() {
#ifdef PICO
return adc_read() / 1023.0 ; // 2^10 - 1
#else
trace("<GPIO.get_adc (input=0) (value=?)");
#endif
}
void gpio_set_level(gpio *g, uint16_t level) {
if (g->has_pwm && g->direction == GPIO_OUT) {
g->level = level;
g->state = level > 0;
#ifdef PICO
pwm_set_gpio_level(g->pin, level);
#else
trace("<GPIO.set_level (pin=%ld) (level=%d)>", g->pin, level);
#endif
}
}
void gpio_set_state(gpio *g, bool state) {
if (!g->has_pwm && g->direction == GPIO_OUT) {
#ifdef PICO
gpio_put(g->pin, state);
#endif
trace("<GPIO.set_state (pin=%ld) (level=%d)>", g->pin, state);
}
}
bool gpio_get_input(gpio* g) {
if (g->direction == GPIO_IN) {
#ifdef PICO
g->state = gpio_get(g->pin);
#else
int value = rand() % (10 + 1);
if (value == 0) {
g->state = false;
return false;
}
g->state = GPIO_INPUT_MOCK_COUNTER++ % value == 0;
#endif
trace("<GPIO.get_input (pin=%ld) (state=%d)>", g->pin, g->state);
return g->state;
}
return false;
}
void gpio_onoff(gpio* g, uint32_t delay_ms, size_t times) {
if (g->direction == GPIO_OUT) {
for (size_t i = 0; i < times; i++) {
gpio_set_state(g, true);
_sleep_ms(delay_ms);
gpio_set_state(g, false);
_sleep_ms(delay_ms);
}
}
}
void init_gpio(void) {
#ifdef PICO
stdio_init_all();
adc_init();
adc_select_input(0); // pin: 26
for (size_t i = 0; i < NB_GPIO; i++) {
gpio_init(GPIOS[i]->pin);
gpio_set_dir(GPIOS[i]->pin, GPIOS[i]->direction);
if (GPIOS[i]->has_pwm) {
uint slice_num = pwm_gpio_to_slice_num(GPIOS[i]->pin);
gpio_set_function(GPIOS[i]->pin, GPIO_FUNC_PWM);
pwm_set_enabled(slice_num, true);
pwm_set_wrap(slice_num, DEFAULT_WRAP_LEVEL);
}
}
gpio_onoff(GPIOS[0], 200, 1);
#endif
}