Skip to content

Commit

Permalink
Merge pull request #855 from avtolstoy/fix-dac-state
Browse files Browse the repository at this point in the history
Added HAL_DAC_Enable()/HAL_DAC_Is_Enabled methods to control DAC state on pin
  • Loading branch information
m-mcgowan committed Mar 10, 2016
2 parents 9b33edd + c8f4006 commit 0caad32
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 8 deletions.
2 changes: 2 additions & 0 deletions hal/inc/dac_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ extern "C" {
#endif

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);

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions hal/inc/hal_dynalib_gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ DYNALIB_FN(hal_gpio, HAL_Interrupts_Suspend)
DYNALIB_FN(hal_gpio, HAL_Interrupts_Restore)

DYNALIB_FN(hal_gpio, HAL_PWM_Write_With_Frequency)
DYNALIB_FN(hal_gpio, HAL_DAC_Is_Enabled)
DYNALIB_FN(hal_gpio, HAL_DAC_Enable)
DYNALIB_END(hal_gpio)

#endif /* HAL_DYNALIB_GPIO_H */
Expand Down
38 changes: 30 additions & 8 deletions hal/src/stm32f2xx/dac_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ static void HAL_DAC_Init()

DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Init(DAC_Channel_2, &DAC_InitStructure);

/* Enable DAC Channel1 */
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_Cmd(DAC_Channel_2, ENABLE);
}

/*
Expand All @@ -77,17 +73,19 @@ static void HAL_DAC_Init()
void HAL_DAC_Write(pin_t pin, uint16_t value)
{
STM32_Pin_Info* PIN_MAP = HAL_Pin_Map();
if (HAL_Get_Pin_Mode(pin) != AN_OUTPUT)
{
HAL_Pin_Mode(pin, AN_OUTPUT);
}

if (dacInitFirstTime == true)
{
HAL_DAC_Init();
dacInitFirstTime = false;
}

if (HAL_Get_Pin_Mode(pin) != AN_OUTPUT)
{
HAL_Pin_Mode(pin, AN_OUTPUT);
HAL_DAC_Enable(pin, 1);
}

if (PIN_MAP[pin].dac_channel == DAC_Channel_1)
{
/* Set the DAC Channel1 data */
Expand All @@ -100,3 +98,27 @@ void HAL_DAC_Write(pin_t pin, uint16_t value)
DAC_SetChannel2Data(DAC_Align_12b_R, value);
}
}

uint8_t HAL_DAC_Is_Enabled(pin_t pin)
{
STM32_Pin_Info* PIN_MAP = HAL_Pin_Map();
if (!dacInitFirstTime && HAL_Get_Pin_Mode(pin) == AN_OUTPUT)
{
if (DAC->CR & (DAC_CR_EN1 << PIN_MAP[pin].dac_channel))
return 1;
}

return 0;
}

uint8_t HAL_DAC_Enable(pin_t pin, uint8_t state)
{
STM32_Pin_Info* PIN_MAP = HAL_Pin_Map();
if (!dacInitFirstTime && HAL_Get_Pin_Mode(pin) == AN_OUTPUT)
{
DAC_Cmd(PIN_MAP[pin].dac_channel, state ? ENABLE : DISABLE);
return 0;
}

return 1;
}
23 changes: 23 additions & 0 deletions hal/src/stm32f2xx/gpio_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "stm32f2xx.h"
#include <stddef.h>
#include "hw_ticks.h"
#include "dac_hal.h"

/* Private typedef ----------------------------------------------------------*/

Expand Down Expand Up @@ -194,6 +195,12 @@ void HAL_GPIO_Write(uint16_t pin, uint8_t value)
{
HAL_Pin_Mode(pin, OUTPUT);
}
else if (PIN_MAP[pin].pin_mode == AN_OUTPUT)
{
if (HAL_DAC_Is_Enabled(pin))
HAL_DAC_Enable(pin, 0);
HAL_Pin_Mode(pin, OUTPUT);
}

if(value == 0)
{
Expand Down Expand Up @@ -224,6 +231,22 @@ int32_t HAL_GPIO_Read(uint16_t pin)
HAL_Pin_Mode(pin, pm);
}
}
else if (PIN_MAP[pin].pin_mode == AN_OUTPUT)
{
PinMode pm = HAL_GPIO_Recall_Pin_Mode();
if(pm == PIN_MODE_NONE)
{
return 0;
}
else
{
// Disable DAC
if (HAL_DAC_Is_Enabled(pin))
HAL_DAC_Enable(pin, 0);
// Restore pin mode
HAL_Pin_Mode(pin, pm);
}
}

if(PIN_MAP[pin].pin_mode == OUTPUT)
{
Expand Down
53 changes: 53 additions & 0 deletions user/tests/wiring/adc_dac/adc_dac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,57 @@ test(ADC_AnalogReadOnPinWithDACShmoo) {
}
assertTrue(errorCount == 0);
}

test(ADC_AnalogReadOnPinWithDACMixedWithDigitalWrite) {
pin_t pin1 = A5;
pin_t pin2 = A1;
pinMode(pin1, INPUT);
pinMode(pin2, INPUT);

// Tests for issue #833 where digitalWrite after analogWrite on DAC pin
// causes pin to latch at last analogWrite value

// Shmoo test
// Set DAC/DAC2 output from 200 to 3896 (ignore non-linearity near 0V or VDD)
// Read back analog and compare for significant difference
int errorCount = 0;
for(int i = 200; i < 3896; i++){
analogWrite(DAC, i);
analogWrite(DAC2, 4096-i);
if (abs(analogRead(pin1)-i) > 200) {
errorCount ++;
}
else if (abs(analogRead(pin2) - 4096 + i) > 200) {
errorCount ++;
}
}
assertTrue(errorCount == 0);

digitalWrite(DAC, LOW);
digitalWrite(DAC2, HIGH);
assertFalse(abs(analogRead(pin1) - 0) > 128);
assertFalse(abs(analogRead(pin2) - 4096) > 128);

// Tests that digitalWrite on DAC doesn't influence analog value on DAC2
// and vice versa
errorCount = 0;
for(int i = 200; i < 3896; i++){
analogWrite(DAC, i);
digitalWrite(DAC2, !digitalRead(DAC2));
if (abs(analogRead(pin1)-i) > 200) {
errorCount ++;
}
}
assertTrue(errorCount == 0);

errorCount = 0;
for(int i = 200; i < 3896; i++){
analogWrite(DAC2, 4096-i);
digitalWrite(DAC, !digitalRead(DAC));
if (abs(analogRead(pin2) - 4096 + i) > 200) {
errorCount ++;
}
}
assertTrue(errorCount == 0);
}
#endif

0 comments on commit 0caad32

Please sign in to comment.