From 7decfee86464f40465ac16eee700e7a688004d22 Mon Sep 17 00:00:00 2001
From: Simon Brummer <brummer.simon@googlemail.com>
Date: Tue, 25 Nov 2014 20:16:15 +0100
Subject: [PATCH] dac driver implementation squashed

---
 boards/stm32f4discovery/Makefile.features |   3 +-
 cpu/stm32f4/periph/dac.c                  | 115 +++++++++++++---------
 drivers/include/periph/dac.h              |  15 ++-
 3 files changed, 77 insertions(+), 56 deletions(-)

diff --git a/boards/stm32f4discovery/Makefile.features b/boards/stm32f4discovery/Makefile.features
index 282e770a43a11..f7ed95610a9c3 100644
--- a/boards/stm32f4discovery/Makefile.features
+++ b/boards/stm32f4discovery/Makefile.features
@@ -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
diff --git a/cpu/stm32f4/periph/dac.c b/cpu/stm32f4/periph/dac.c
index c833ee1ca987f..81b2d348ed68e 100644
--- a/cpu/stm32f4/periph/dac.c
+++ b/cpu/stm32f4/periph/dac.c
@@ -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
@@ -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>
  *
  * @}
  */
@@ -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;
 }
@@ -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;
 }
diff --git a/drivers/include/periph/dac.h b/drivers/include/periph/dac.h
index eeda6e2e7bcd9..b673769bd529f 100644
--- a/drivers/include/periph/dac.h
+++ b/drivers/include/periph/dac.h
@@ -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
@@ -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);
 
@@ -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);
 
@@ -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);
 
@@ -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 */
 /** @} */