Skip to content

Commit

Permalink
dac driver implementation squashed
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Brummer committed Nov 25, 2014
1 parent ffc1f7e commit 7decfee
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 56 deletions.
3 changes: 1 addition & 2 deletions boards/stm32f4discovery/Makefile.features
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
FEATURES_PROVIDED += periph_gpio periph_spi periph_i2c periph_pwm periph_random periph_adc cpp

FEATURES_PROVIDED += periph_gpio periph_spi periph_i2c periph_pwm periph_random periph_adc periph_dac cpp
115 changes: 66 additions & 49 deletions cpu/stm32f4/periph/dac.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
* Copyright (C) 2014 Simon Brummer
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
Expand All @@ -13,7 +13,7 @@
* @file
* @brief Low-level DAC driver implementation
*
* @author Simon Brummer(simon.brummer@haw-hamburg.de)
* @author Simon Brummer<simon.brummer@haw-hamburg.de>
*
* @}
*/
Expand All @@ -35,78 +35,87 @@ dac_config_t dac_config[DAC_NUMOF];

int8_t dac_init(dac_t dev, dac_precision_t precision)
{

DAC_TypeDef *dac = 0;
dac_poweron(dev);

switch (dev) {
#if DAC_0_EN
case DAC_0:
dac = DAC_0_DEV;
DAC_0_PORT_CLKEN();
// Set Mode to analoge out, disable Pullup Pulldown Resistors for both channels
DAC_0_PORT->MODER |= (3 << (DAC_0_CH0_PIN * 2) | 3 << (DAC_0_CH1_PIN * 2));
DAC_0_PORT->PUPDR &= ~(3 << (DAC_0_CH0_PIN * 2) | 3 << (DAC_0_CH1_PIN * 2));
break;
case DAC_0:
dac = DAC_0_DEV;
DAC_0_PORT_CLKEN();
/* Set Mode to analoge out, disable Pullup Pulldown Resistors for both channels */
DAC_0_PORT->MODER |= (3 << (DAC_0_CH0_PIN * 2) | 3 << (DAC_0_CH1_PIN * 2));
DAC_0_PORT->PUPDR &= ~(3 << (DAC_0_CH0_PIN * 2) | 3 << (DAC_0_CH1_PIN * 2));
break;
#endif
default:
/* Unknown Device */
return -1;
}

// Select Shift value to normalize given Value
/* Select Shift value to normalize given Value */
switch(precision) {
case DAC_RES_6BIT:
dac_config[dev].shift_mod = 0x06; // 2^6 << 6 = 2^12
break;
case DAC_RES_8BIT:
dac_config[dev].shift_mod = 0x04; // 2^8 << 4 = 2^12
break;
case DAC_RES_10BIT:
dac_config[dev].shift_mod = 0x02; // 2^10 << 2 = 2^12
break;
case DAC_RES_12BIT:
dac_config[dev].shift_mod = 0x00; // 2^12 << 0 = 2^12
break;
// Not Supported Resolutions
case DAC_RES_14BIT:
case DAC_RES_16BIT:
dac_poweroff(dev);
return -1;
case DAC_RES_6BIT:
dac_config[dev].shift_mod = 0x06; /* 2^6 << 6 = 2^12 */
break;
case DAC_RES_8BIT:
dac_config[dev].shift_mod = 0x04; /* 2^8 << 4 = 2^12 */
break;
case DAC_RES_10BIT:
dac_config[dev].shift_mod = 0x02; /* 2^10 << 2 = 2^12 */
break;
case DAC_RES_12BIT:
dac_config[dev].shift_mod = 0x00; /* 2^12 << 0 = 2^12 */
break;
/* Not Supported Resolutions */
case DAC_RES_14BIT:
case DAC_RES_16BIT:
default:
dac_poweroff(dev);
return -2;
break;
}

// Enable Channels, Clear Output
/* Enable Channels, Clear Output */
dac->CR = 0;
dac->CR |= (DAC_CR_EN1 | DAC_CR_EN2);
dac->DHR12R1 = 0;
dac->DHR12R2 = 0;

return 0;

}

int8_t dac_write(dac_t dev, uint8_t channel, uint16_t value)
{
DAC_TypeDef *dac = 0;
uint16_t val = value << dac_config[dev].shift_mod;
DAC_TypeDef* __attribute__((unused)) dac = 0;
uint16_t __attribute__((unused)) val = value << dac_config[dev].shift_mod;

switch(dev){
#if DAC_0_EN
case DAC_0:
dac = DAC_0_DEV;

// Check if given value is in Range.
if( DAC_MAX_12BIT < val ){
return -1;
/* Value out of Range */
return -3;
}

switch(channel){
case 0: dac->DHR12R1 = val; break;
case 1: dac->DHR12R2 = val; break;
// Unknown Channel
default:
return -2;
case 0:
dac->DHR12R1 = val;
break;
case 1:
dac->DHR12R2 = val;
break;
/* Invalid Channel */
default:
return -2;
}
break;
#endif
/* Unknown Device */
default:
return -1;
}
return 0;
}
Expand All @@ -115,31 +124,39 @@ int8_t dac_poweron(dac_t dev)
{
switch (dev){
#if DAC_0_EN
case DAC_0:
DAC_0_CLKEN();
return 0;
case DAC_0:
DAC_0_CLKEN();
break;
#endif
default:
/* Unknown Device */
return -1;
}
return -1;
return 0;
}

int8_t dac_poweroff(dac_t dev)
{
switch (dev) {
#if DAC_0_EN
case DAC_0:
DAC_0_CLKDIS();
return 0;
case DAC_0:
DAC_0_CLKDIS();
break;
#endif
default:
/* Unknown Device */
return -1;
}
return -1;
return 0;
}

uint16_t dac_map(dac_t dev, int value, int min, int max){
uint16_t dac_map(dac_t dev, int value, int min, int max)
{
return dac_mapf(dev, (int) value, (int) min, (int) max);
}

uint16_t dac_mapf(dac_t dev, float value, float min, float max){
uint16_t dac_mapf(dac_t dev, float value, float min, float max)
{
uint16_t val_12_bit = ((value - min) * DAC_MAX_12BIT)/(max-min);
return val_12_bit >> dac_config[dev].shift_mod;
}
Expand Down
15 changes: 10 additions & 5 deletions drivers/include/periph/dac.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Freie Universität Berlin
* Copyright (C) 2014 Simon Brummer
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
Expand Down Expand Up @@ -74,7 +74,8 @@ typedef enum {
* @param[in] precision the precision to use for conversion
*
* @return 0 on success
* @return -1 on precision not available
* @return -1 on unknown DAC Device
* @return -2 on precision not available
*/
int8_t dac_init(dac_t dev, dac_precision_t precision);

Expand All @@ -86,8 +87,9 @@ int8_t dac_init(dac_t dev, dac_precision_t precision);
* @param[in] value the value to write onto DAC.
*
* @return 0 on success
* @return -1 if value is out of range.
* @return -1 on unknown DAC Device
* @return -2 on invalid channel
* @return -3 if value is out of range.
*/
int8_t dac_write(dac_t dev, uint8_t channel, uint16_t value);

Expand Down Expand Up @@ -124,7 +126,7 @@ int8_t dac_poweroff(dac_t dev);
* @param[in] min the lower bound of the target interval
* @param[in] max the upper bound of the target interval
*
* @return the mapped value
* @return the mapped value, in valid DAC range
*/
uint16_t dac_map(dac_t dev, int value, int min, int max);

Expand All @@ -138,11 +140,14 @@ uint16_t dac_map(dac_t dev, int value, int min, int max);
* @param[in] min the lower bound of the target interval
* @param[in] max the upper bound of the target interval
*
* @return the mapped value
* @return the mapped value, in valid DAC range
*/
uint16_t dac_mapf(dac_t dev, float value, float min, float max);

#endif/* DAC_NUMOF */

#ifdef __cplusplus
}
#endif
#endif /* __DAC_H */
/** @} */

0 comments on commit 7decfee

Please sign in to comment.