From 22fb4bdfe55f73a0e254878f6a5844edf8bd9401 Mon Sep 17 00:00:00 2001 From: Bigbits Date: Mon, 18 Mar 2019 18:28:23 +0800 Subject: [PATCH] Add analogWriter() Signed-off-by: Bigbits --- cores/arduino/Arduino.h | 2 +- cores/arduino/wiring_analog.c | 101 +++++++++++++++++++++++++++++++ cores/arduino/wiring_analog.h | 76 +++++++++++++++++++++++ variants/standard/pins_arduino.h | 1 - variants/standard/sipeedm1.h | 10 ++- 5 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 cores/arduino/wiring_analog.c create mode 100644 cores/arduino/wiring_analog.h diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 25253d3..5410ce4 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -82,7 +82,7 @@ void noTone(uint8_t _pin); //#include "variant.h" #include "wiring_digital.h" -//#include "wiring_analog.h" +#include "wiring_analog.h" //#include "wiring_shift.h" //#include "WInterrupts.h" diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c new file mode 100644 index 0000000..dcf34db --- /dev/null +++ b/cores/arduino/wiring_analog.c @@ -0,0 +1,101 @@ +#include "Arduino.h" +#include "wiring_analog.h" +#include "pwm.h" +#include "fpioa.h" +#include "stdio.h" + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +static int _readResolution = 0; +static int _writeResolution = 8; +static double _writeFreq = 200000; + +static pwm_fpio_set_t pwm_pins[VARIANT_NUM_PWM]={ + {.channel = PWM_CHANNEL_0, .device = PWM_DEVICE_0, .inuse = 0x0}, + {.channel = PWM_CHANNEL_1, .device = PWM_DEVICE_0, .inuse = 0x0}, + {.channel = PWM_CHANNEL_2, .device = PWM_DEVICE_0, .inuse = 0x0}, + {.channel = PWM_CHANNEL_3, .device = PWM_DEVICE_0, .inuse = 0x0}, + {.channel = PWM_CHANNEL_0, .device = PWM_DEVICE_1, .inuse = 0x0}, + {.channel = PWM_CHANNEL_1, .device = PWM_DEVICE_1, .inuse = 0x0}, + {.channel = PWM_CHANNEL_2, .device = PWM_DEVICE_1, .inuse = 0x0}, + {.channel = PWM_CHANNEL_3, .device = PWM_DEVICE_1, .inuse = 0x0}, + {.channel = PWM_CHANNEL_0, .device = PWM_DEVICE_2, .inuse = 0x0}, + {.channel = PWM_CHANNEL_1, .device = PWM_DEVICE_2, .inuse = 0x0}, + {.channel = PWM_CHANNEL_2, .device = PWM_DEVICE_2, .inuse = 0x0}, + {.channel = PWM_CHANNEL_3, .device = PWM_DEVICE_2, .inuse = 0x0}, +}; +static uint8_t _pwm_used_pin = 0; +/* K210 CAN'T READ */ +void analogReadResolution(int res){ + _readResolution = res; +} + +void analogWriteResolution(int res){ + _writeResolution = res; +} + +void analogWriteFrequency(double res){ + _writeFreq = res; +} + +void analogWritePhase(uint8_t pin, uint32_t phase) +{ + +} + +void analogOutputInit(void) +{ + +} + +void analogWrite(uint8_t ucPin, uint32_t ulValue ) +{ + int8_t _pin = k210FpioSet(ucPin); + double _duty; + if(_pin >= 0){ + _duty = dValueToDuty(ulValue); + pwm_set_frequency(pwm_pins[_pin].device, pwm_pins[_pin].channel,_writeFreq,_duty>1?1:_duty); + pwm_set_enable(pwm_pins[_pin].device, pwm_pins[_pin].channel,1); + } +} + +double dValueToDuty(uint32_t ulValue){ + return (double)ulValue/(double)((1<<_writeResolution)-1); +} + +int8_t k210FpioSet(uint8_t ucPin) +{ + int8_t _pin; + for(int i = 0; i < _pwm_used_pin; i++){ + if(ucPin == pwm_pins[i].inuse){ + return i; + } + } + _pin = getPwmPin(); + if(_pin >= 0){ + fpioa_set_function(ucPin, FUNC_TIMER0_TOGGLE1 + _pin); + pwm_pins[_pin].inuse = ucPin; + pwm_init(pwm_pins[_pin].device); + _pwm_used_pin += 1; + return _pin; + }else{ + return -1; + } + +} + +int8_t getPwmPin(void) +{ + for(int i = _pwm_used_pin; i < VARIANT_NUM_PWM; i++){ + if(pwm_pins[i].inuse == 0){ + return i; + } + } + return -1; +} + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/cores/arduino/wiring_analog.h b/cores/arduino/wiring_analog.h new file mode 100644 index 0000000..a439528 --- /dev/null +++ b/cores/arduino/wiring_analog.h @@ -0,0 +1,76 @@ + +#ifndef _WIRING_ANALOG_ +#define _WIRING_ANALOG_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + + +typedef enum _eAnalogReference +{ + AR_DEFAULT, +} eAnalogReference ; + + +/* + * \brief Configures the reference voltage used for analog input (i.e. the value used as the top of the input range). + * This function is kept only for compatibility with existing AVR based API. + * + * \param ulMmode Should be set to AR_DEFAULT. + */ +extern void analogReference( eAnalogReference ulMode ) ; + +/* + * \brief Writes an analog value (PWM wave) to a pin. + * + * \param ulPin + * \param ulValue + */ +extern void analogWrite( uint8_t ucPin, uint32_t ulValue ) ; + +/* + * \brief Reads the value from the specified analog pin. + * + * \param ulPin + * + * \return Read value from selected pin, if no error. + */ +extern uint32_t analogRead( uint32_t ulPin ) ; + +/* + * \brief Set the resolution of analogRead return values. Default is 10 bits (range from 0 to 1023). + * + * \param res + */ +extern void analogReadResolution(int res); + +/* + * \brief Set the resolution of analogWrite parameters. Default is 8 bits (range from 0 to 255). + * + * \param res + */ +extern void analogWriteResolution(int res); + +/* + * \brief Set the frequency of analogWrite PWM output. Default is 980 Hz (range from 20 to 25000). + * + * \param res + */ +extern void analogWriteFrequency(double freq); + +extern void analogWritePhase(uint8_t pin, uint32_t phase); + +extern void analogOutputInit( void ) ; + +extern double dValueToDuty(uint32_t ulValue); + +extern int8_t k210FpioSet(uint8_t ucPin); + +extern int8_t getPwmPin(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif /* _WIRING_ANALOG_ */ \ No newline at end of file diff --git a/variants/standard/pins_arduino.h b/variants/standard/pins_arduino.h index 04185cd..d6056d6 100644 --- a/variants/standard/pins_arduino.h +++ b/variants/standard/pins_arduino.h @@ -4,4 +4,3 @@ #include "sipeedm1.h" #endif - diff --git a/variants/standard/sipeedm1.h b/variants/standard/sipeedm1.h index 3274978..648ef45 100644 --- a/variants/standard/sipeedm1.h +++ b/variants/standard/sipeedm1.h @@ -7,7 +7,7 @@ #include "platform.h" #include "Arduino.h" - +#include "pwm.h" /* BOARD PIN DEFINE */ /* LEDs */ @@ -59,9 +59,15 @@ static const uint8_t MOSI = SPI0_MOSI; static const uint8_t MISO = SPI0_MISO; static const uint8_t SCK = SPI0_SCLK; +typedef struct _pwm_fpio_set_t{ + pwm_channel_number_t channel; + pwm_device_number_t device; + uint8_t inuse; +}pwm_fpio_set_t; + #define VARIANT_NUM_GPIOHS (32) #define VARIANT_NUM_GPIO ( 8) -#define VARIANT_NUM_PWM ( 3) +#define VARIANT_NUM_PWM (12) #define VARIANT_NUM_I2C ( 3) #define VARIANT_NUM_SPI ( 3) #define VARIANT_NUM_UART ( 3)