Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAC and PWM resolution #991

Merged
merged 11 commits into from
Jun 10, 2016
53 changes: 51 additions & 2 deletions docs/reference/firmware.md
Original file line number Diff line number Diff line change
Expand Up @@ -2204,8 +2204,8 @@ analogWrite(pin, value, frequency);
`analogWrite()` takes two or three arguments:

- `pin`: the number of the pin whose value you wish to set
- `value`: the duty cycle: between 0 (always off) and 255 (always on).
- `frequency`: the PWM frequency: between 1 Hz and 65535 Hz (default 500 Hz).
- `value`: the duty cycle: between 0 (always off) and 255 (always on). *Since 0.6.0:* between 0 and 255 (default 8-bit resolution) or `2^(analogWriteResolution(pin)) - 1` in general.
- `frequency`: the PWM frequency: between 1 Hz and 65535 Hz (default 500 Hz). *Since 0.6.0:* between 1 Hz and `analogWriteMaxFrequency(pin)`.

**NOTE:** `pinMode(pin, OUTPUT);` is required before calling `analogWrite(pin, value);` or else the `pin` will not be initialized as a PWM output and set to the desired duty cycle.

Expand Down Expand Up @@ -2245,6 +2245,55 @@ The PWM frequency must be the same for pins in the same timer group.

**NOTE:** When used with PWM capable pins, the `analogWrite()` function sets up these pins as PWM only. {{#unless core}}This function operates differently when used with the [`Analog Output (DAC)`](#analog-output-dac-) pins.{{/unless}}

{{#unless core}}
### analogWriteResolution() (PWM and DAC)
{{/unless}}
{{#if core}}
### analogWriteResolution() (PWM)
{{/if}}

*Since 0.6.0.*

Sets or retrieves the resolution of `analogWrite()` function of a particular pin.

`analogWriteResolution()` takes one or two arguments:

- `pin`: the number of the pin whose resolution you wish to set or retrieve
- `resolution`: (optional) resolution in bits. The value can range from 2 to 31 bits. If the resolution is not supported, it will not be applied.

`analogWriteResolution()` returns currently set resolution.

```C++
// EXAMPLE USAGE
pinMode(D1, OUTPUT); // sets the pin as output
analogWriteResolution(D1, 12); // sets analogWrite resolution to 12 bits
analogWrite(D1, 3000, 1000); // 3000/4095 = ~73% duty cycle at 1kHz
```

{{#unless core}}
**NOTE:** DAC pins `DAC1` (`A6`) and `DAC2` (`A3`) support only either 8-bit or 12-bit (default) resolutions.
{{/unless}}

**NOTE:** The resolution also affects maximum frequency that can be used with `analogWrite()`. The maximum frequency allowed with current resolution can be checked by calling `analogWriteMaxFrequency()`.

### analogWriteMaxFrequency() (PWM)

*Since 0.6.0.*

Returns maximum frequency that can be used with `analogWrite()` on this pin.

`analogWriteMaxFrequency()` takes one argument:

- `pin`: the number of the pin

```C++
// EXAMPLE USAGE
pinMode(D1, OUTPUT); // sets the pin as output
analogWriteResolution(D1, 12); // sets analogWrite resolution to 12 bits
int maxFreq = analogWriteMaxFrequency(D1);
analogWrite(D1, 3000, maxFreq / 2); // 3000/4095 = ~73% duty cycle
```

{{#unless core}}
### Analog Output (DAC)

Expand Down
3 changes: 3 additions & 0 deletions hal/inc/dac_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ extern "C" {
void HAL_DAC_Write(pin_t pin, uint16_t value);
uint8_t HAL_DAC_Is_Enabled(pin_t pin);
uint8_t HAL_DAC_Enable(pin_t pin, uint8_t state);
uint8_t HAL_DAC_Get_Resolution(pin_t pin);
void HAL_DAC_Set_Resolution(pin_t pin, uint8_t resolution);
void HAL_DAC_Enable_Buffer(pin_t pin, uint8_t state);

#ifdef __cplusplus
}
Expand Down
12 changes: 12 additions & 0 deletions hal/inc/hal_dynalib_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ DYNALIB_FN(22, hal_gpio, HAL_PWM_Write_With_Frequency, void(uint16_t, uint8_t, u
DYNALIB_FN(23, hal_gpio, HAL_DAC_Is_Enabled, uint8_t(pin_t))
DYNALIB_FN(24, hal_gpio, HAL_DAC_Enable, uint8_t(pin_t, uint8_t))

DYNALIB_FN(25, hal_gpio, HAL_DAC_Get_Resolution, uint8_t(pin_t))
DYNALIB_FN(26, hal_gpio, HAL_DAC_Set_Resolution, void(pin_t, uint8_t))
DYNALIB_FN(27, hal_gpio, HAL_DAC_Enable_Buffer, void(pin_t pin, uint8_t state))
DYNALIB_FN(28, hal_gpio, HAL_PWM_Get_Resolution, uint8_t(uint16_t))
DYNALIB_FN(29, hal_gpio, HAL_PWM_Set_Resolution, void(uint16_t, uint8_t))
DYNALIB_FN(30, hal_gpio, HAL_PWM_Write_Ext, void(uint16_t, uint32_t))
DYNALIB_FN(31, hal_gpio, HAL_PWM_Write_With_Frequency_Ext, void(uint16_t, uint32_t, uint32_t))
DYNALIB_FN(32, hal_gpio, HAL_PWM_Get_Frequency_Ext, uint32_t(uint16_t))
DYNALIB_FN(33, hal_gpio, HAL_PWM_Get_AnalogValue_Ext, uint32_t(uint16_t))
DYNALIB_FN(34, hal_gpio, HAL_PWM_Get_Max_Frequency, uint32_t(uint16_t))


DYNALIB_END(hal_gpio)

#endif /* HAL_DYNALIB_GPIO_H */
Expand Down
8 changes: 8 additions & 0 deletions hal/inc/pwm_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,17 @@ extern "C" {

void HAL_PWM_Write(uint16_t pin, uint8_t value);
void HAL_PWM_Write_With_Frequency(uint16_t pin, uint8_t value, uint16_t pwm_frequency);
void HAL_PWM_Write_Ext(uint16_t pin, uint32_t value);
void HAL_PWM_Write_With_Frequency_Ext(uint16_t pin, uint32_t value, uint32_t pwm_frequency);
uint16_t HAL_PWM_Get_Frequency(uint16_t pin);
uint16_t HAL_PWM_Get_AnalogValue(uint16_t pin);
uint32_t HAL_PWM_Get_Frequency_Ext(uint16_t pin);
uint32_t HAL_PWM_Get_AnalogValue_Ext(uint16_t pin);
uint32_t HAL_PWM_Get_Max_Frequency(uint16_t pin);
void HAL_PWM_UpdateDutyCycle(uint16_t pin, uint16_t value);
void HAL_PWM_UpdateDutyCycle_Ext(uint16_t pin, uint32_t value);
uint8_t HAL_PWM_Get_Resolution(uint16_t pin);
void HAL_PWM_Set_Resolution(uint16_t pin, uint8_t resolution);

#ifdef __cplusplus
}
Expand Down
Loading