114 lines
2.6 KiB
C
114 lines
2.6 KiB
C
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
|
|
|
#include <Arduino.h>
|
|
#include <pwm_pub.h>
|
|
#include <saradc_pub.h>
|
|
|
|
static GPIO_INDEX pwmToGpio[] = {
|
|
GPIO6, // PWM0
|
|
GPIO7, // PWM1
|
|
GPIO8, // PWM2
|
|
GPIO9, // PWM3
|
|
GPIO24, // PWM4
|
|
GPIO26, // PWM5
|
|
};
|
|
|
|
static GPIO_INDEX adcToGpio[] = {
|
|
-1, // ADC0 - VBAT
|
|
GPIO4, // ADC1
|
|
GPIO5, // ADC2
|
|
GPIO23, // ADC3
|
|
GPIO2, // ADC4
|
|
GPIO3, // ADC5
|
|
GPIO12, // ADC6
|
|
GPIO13, // ADC7
|
|
};
|
|
|
|
static uint8_t gpioToPwm(GPIO_INDEX gpio) {
|
|
for (uint8_t i = 0; i < sizeof(pwmToGpio); i++) {
|
|
if (pwmToGpio[i] == gpio)
|
|
return i;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static uint8_t gpioToAdc(GPIO_INDEX gpio) {
|
|
for (uint8_t i = 0; i < sizeof(adcToGpio); i++) {
|
|
if (adcToGpio[i] == gpio)
|
|
return i;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static pwm_param_t pwm;
|
|
static uint16_t adcData[1];
|
|
|
|
uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
|
PinInfo *pin = pinInfo(pinNumber);
|
|
if (!pin)
|
|
return 0;
|
|
if (!pinSupported(pin, PIN_ADC))
|
|
return 0;
|
|
|
|
UINT32 status;
|
|
saradc_desc_t adc;
|
|
DD_HANDLE handle;
|
|
saradc_config_param_init(&adc);
|
|
adc.channel = gpioToAdc(pin->gpio);
|
|
adc.mode = ADC_CONFIG_MODE_CONTINUE;
|
|
adc.pData = adcData;
|
|
adc.data_buff_size = 1;
|
|
handle = ddev_open(SARADC_DEV_NAME, &status, (uint32_t)&adc);
|
|
if (status)
|
|
return 0;
|
|
// wait for data
|
|
while (!adc.has_data || adc.current_sample_data_cnt < 1) {
|
|
delay(1);
|
|
}
|
|
ddev_control(handle, SARADC_CMD_RUN_OR_STOP_ADC, (void *)false);
|
|
ddev_close(handle);
|
|
return adcData[0];
|
|
}
|
|
|
|
uint16_t analogReadMaxVoltage(pin_size_t pinNumber) {
|
|
return 3300;
|
|
}
|
|
|
|
void analogWrite(pin_size_t pinNumber, int value) {
|
|
PinInfo *pin = pinInfo(pinNumber);
|
|
if (!pin)
|
|
return;
|
|
if (!pinSupported(pin, PIN_PWM))
|
|
return;
|
|
|
|
float percent = value * 1.0 / (1 << _analogWriteResolution);
|
|
uint32_t dutyCycle = percent * _analogWritePeriod * 26 - 1;
|
|
pwm.channel = gpioToPwm(pin->gpio);
|
|
pwm.duty_cycle = dutyCycle;
|
|
|
|
if (!pinEnabled(pin, PIN_PWM)) {
|
|
// enable PWM and set its value
|
|
pwm.cfg.bits.en = PWM_ENABLE;
|
|
pwm.cfg.bits.int_en = PWM_INT_DIS;
|
|
pwm.cfg.bits.mode = PWM_PWM_MODE;
|
|
pwm.cfg.bits.clk = PWM_CLK_26M;
|
|
pwm.end_value = 26 * _analogWritePeriod - 1;
|
|
pwm.p_Int_Handler = NULL;
|
|
__wrap_bk_printf_disable();
|
|
sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, &pwm);
|
|
__wrap_bk_printf_enable();
|
|
pin->enabled &= ~PIN_GPIO;
|
|
pin->enabled |= PIN_PWM;
|
|
} else if (value == 0) {
|
|
// disable PWM
|
|
pwm.cfg.bits.en = PWM_DISABLE;
|
|
__wrap_bk_printf_disable();
|
|
sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, &pwm);
|
|
__wrap_bk_printf_enable();
|
|
pin->enabled &= ~PIN_PWM;
|
|
} else {
|
|
// update duty cycle
|
|
sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &pwm);
|
|
}
|
|
}
|