diff --git a/README.md b/README.md index 490d0ea..073e180 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Note: this list will probably change with each functionality update. --------------------|--------------- Core functions | ✔️ GPIO/PWM/IRQ | ✔️/✔️/✔️ -Analog input | ❓ +Analog input | ✔️ UART I/O | ✔️ Flash I/O | ✔️ **CORE LIBRARIES** | diff --git a/arduino/libretuya/core/LibreTuyaCustom.h b/arduino/libretuya/core/LibreTuyaCustom.h index b2ebd16..b5184ff 100644 --- a/arduino/libretuya/core/LibreTuyaCustom.h +++ b/arduino/libretuya/core/LibreTuyaCustom.h @@ -6,6 +6,11 @@ extern "C" { #endif +/** + * @brief Read voltage from analog input (in millivolts). + */ +uint16_t analogReadVoltage(pin_size_t pinNumber); + /** * @brief Set resolution of values (in bits) returned by analogRead(). */ diff --git a/arduino/realtek-ambz/cores/arduino/wiring_analog.c b/arduino/realtek-ambz/cores/arduino/wiring_analog.c index 878a1cd..c289304 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring_analog.c +++ b/arduino/realtek-ambz/cores/arduino/wiring_analog.c @@ -27,10 +27,9 @@ analogin_t adc1; analogin_t adc2; analogin_t adc3; -static const float ADC_slope1 = (3.12) / (3410.0 - 674.0); -static const float ADC_slope2 = (3.3 - 3.12) / (3454.0 - 3410.0); - bool g_adc_enabled[] = {false, false, false}; +// from realtek_amebaz_va0_example/example_sources/adc_vbat/src/main.c +#define AD2MV(ad, offset, gain) (((ad >> 4) - offset) * 1000 / gain) extern void *gpio_pin_struct[]; @@ -40,6 +39,8 @@ static int _readResolution = 10; static int _writeResolution = 8; static int _writePeriod = 20000; // 50 Hz +// TODO implement custom ADC calibration + void analogReadResolution(int res) { _readResolution = res; } @@ -56,40 +57,29 @@ void analogWriteResolution(int res) { _writeResolution = res; } -static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) { - if (from == to) - return value; - if (from > to) - return value >> (from - to); - else - return value << (to - from); -} - uint8_t analog_reference = AR_DEFAULT; void analogReference(uint8_t mode) { analog_reference = mode; } -int analogRead(pin_size_t pinNumber) { - uint32_t ulValue = 0; - uint32_t ulChannel; +uint16_t analogReadVoltage(pin_size_t pinNumber) { uint16_t ret = 0; - float voltage; - float adc_value; - switch (pinNumber) { - case PIN_A0: - if (g_adc_enabled[0] == false) { - analogin_init(&adc1, AD_1); - g_adc_enabled[0] = true; - } case PIN_A1: if (g_adc_enabled[1] == false) { analogin_init(&adc2, AD_2); g_adc_enabled[1] = true; } ret = analogin_read_u16(&adc2); + // AD_1 - 0.0V-5.0V + return AD2MV(ret, 0x496, 0xBA); + case PIN_A0: + if (g_adc_enabled[0] == false) { + analogin_init(&adc1, AD_1); + g_adc_enabled[0] = true; + } + ret = analogin_read_u16(&adc1); break; case PIN_A2: if (g_adc_enabled[2] == false) { @@ -99,20 +89,21 @@ int analogRead(pin_size_t pinNumber) { ret = analogin_read_u16(&adc3); break; default: - printf("%s : pinNumber %d wrong\n", __FUNCTION__, pinNumber); return 0; } - ret >>= 4; - if (ret < 674) { - voltage = 0; - } else if (ret > 3410) { - voltage = (float)(ret - 3410) * ADC_slope2 + 3.12; - } else { - voltage = (float)(ret - 674) * ADC_slope1; - } + // AD_0, AD_2 - 0.0V-3.3V + return AD2MV(ret, 0x418, 0x342); +} - ret = round((1 << _readResolution) * voltage / 3.3); +int analogRead(pin_size_t pinNumber) { + float voltage = analogReadVoltage(pinNumber); + uint16_t ret = 0; + if (pinNumber != PIN_A1) { + ret = round((1 << _readResolution) * voltage / 3300); + } else { + ret = round((1 << _readResolution) * voltage / 5000); + } if (ret >= (1 << _readResolution)) ret = (1 << _readResolution) - 1; return ret; diff --git a/arduino/realtek-ambz/cores/arduino/wiring_digital.c b/arduino/realtek-ambz/cores/arduino/wiring_digital.c index 8923e42..71fb53d 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring_digital.c +++ b/arduino/realtek-ambz/cores/arduino/wiring_digital.c @@ -40,6 +40,10 @@ void pinMode(pin_size_t pinNumber, PinModeArduino pinMode) { // Nothing changes in pin mode return; + if ((g_APinDescription[pinNumber].ulPinAttribute & PIO_GPIO) != PIO_GPIO) + // cannot set ADC as I/O + return; + /* if (g_APinDescription[pinNumber].ulPinType == PIO_PWM) { // If this pin has been configured as PWM, then it cannot change to another mode return;