STM32F3 DAC does not work with simultaneous output. I modified "analogout_api.c" to fix it.

Dependents:   AnalogOut-HelloWorld

Committer:
tttogasawara
Date:
Wed Nov 02 02:08:54 2016 +0000
Revision:
0:99b50c8f8edd
STM32F3 DAC does not work with 3ch simultaneous output. I modified "analogout_api.c" to fix it.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tttogasawara 0:99b50c8f8edd 1 /* mbed Microcontroller Library
tttogasawara 0:99b50c8f8edd 2 * Copyright (c) 2015, STMicroelectronics
tttogasawara 0:99b50c8f8edd 3 * All rights reserved.
tttogasawara 0:99b50c8f8edd 4 *
tttogasawara 0:99b50c8f8edd 5 * Redistribution and use in source and binary forms, with or without
tttogasawara 0:99b50c8f8edd 6 * modification, are permitted provided that the following conditions are met:
tttogasawara 0:99b50c8f8edd 7 *
tttogasawara 0:99b50c8f8edd 8 * 1. Redistributions of source code must retain the above copyright notice,
tttogasawara 0:99b50c8f8edd 9 * this list of conditions and the following disclaimer.
tttogasawara 0:99b50c8f8edd 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
tttogasawara 0:99b50c8f8edd 11 * this list of conditions and the following disclaimer in the documentation
tttogasawara 0:99b50c8f8edd 12 * and/or other materials provided with the distribution.
tttogasawara 0:99b50c8f8edd 13 * 3. Neither the name of STMicroelectronics nor the names of its contributors
tttogasawara 0:99b50c8f8edd 14 * may be used to endorse or promote products derived from this software
tttogasawara 0:99b50c8f8edd 15 * without specific prior written permission.
tttogasawara 0:99b50c8f8edd 16 *
tttogasawara 0:99b50c8f8edd 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
tttogasawara 0:99b50c8f8edd 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
tttogasawara 0:99b50c8f8edd 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
tttogasawara 0:99b50c8f8edd 20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
tttogasawara 0:99b50c8f8edd 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
tttogasawara 0:99b50c8f8edd 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
tttogasawara 0:99b50c8f8edd 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
tttogasawara 0:99b50c8f8edd 24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
tttogasawara 0:99b50c8f8edd 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
tttogasawara 0:99b50c8f8edd 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
tttogasawara 0:99b50c8f8edd 27 */
tttogasawara 0:99b50c8f8edd 28 #include "mbed_assert.h"
tttogasawara 0:99b50c8f8edd 29 #include "analogout_api.h"
tttogasawara 0:99b50c8f8edd 30
tttogasawara 0:99b50c8f8edd 31 #if DEVICE_ANALOGOUT
tttogasawara 0:99b50c8f8edd 32
tttogasawara 0:99b50c8f8edd 33 #include "cmsis.h"
tttogasawara 0:99b50c8f8edd 34 #include "pinmap.h"
tttogasawara 0:99b50c8f8edd 35 #include "mbed_error.h"
tttogasawara 0:99b50c8f8edd 36 #include "PeripheralPins.h"
tttogasawara 0:99b50c8f8edd 37
tttogasawara 0:99b50c8f8edd 38 #define DAC_RANGE (0xFFF) // 12 bits
tttogasawara 0:99b50c8f8edd 39 #define DAC_NB_BITS (12)
tttogasawara 0:99b50c8f8edd 40
tttogasawara 0:99b50c8f8edd 41 static DAC_HandleTypeDef DacHandle1;
tttogasawara 0:99b50c8f8edd 42 static DAC_HandleTypeDef DacHandle2;
tttogasawara 0:99b50c8f8edd 43
tttogasawara 0:99b50c8f8edd 44 // These variables are used for the "free" function
tttogasawara 0:99b50c8f8edd 45 static int pa4_used = 0;
tttogasawara 0:99b50c8f8edd 46 static int pa5_used = 0;
tttogasawara 0:99b50c8f8edd 47
tttogasawara 0:99b50c8f8edd 48 void analogout_init(dac_t *obj, PinName pin)
tttogasawara 0:99b50c8f8edd 49 {
tttogasawara 0:99b50c8f8edd 50 DAC_ChannelConfTypeDef sConfig;
tttogasawara 0:99b50c8f8edd 51
tttogasawara 0:99b50c8f8edd 52 // Get the peripheral name from the pin and assign it to the object
tttogasawara 0:99b50c8f8edd 53 obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
tttogasawara 0:99b50c8f8edd 54 MBED_ASSERT(obj->dac != (DACName)NC);
tttogasawara 0:99b50c8f8edd 55
tttogasawara 0:99b50c8f8edd 56 // Get the pin function and assign the used channel to the object
tttogasawara 0:99b50c8f8edd 57 uint32_t function = pinmap_function(pin, PinMap_DAC);
tttogasawara 0:99b50c8f8edd 58 MBED_ASSERT(function != (uint32_t)NC);
tttogasawara 0:99b50c8f8edd 59 obj->channel = STM_PIN_CHANNEL(function);
tttogasawara 0:99b50c8f8edd 60
tttogasawara 0:99b50c8f8edd 61 // Configure GPIO
tttogasawara 0:99b50c8f8edd 62 pinmap_pinout(pin, PinMap_DAC);
tttogasawara 0:99b50c8f8edd 63
tttogasawara 0:99b50c8f8edd 64 // Save the pin for future use
tttogasawara 0:99b50c8f8edd 65 obj->pin = pin;
tttogasawara 0:99b50c8f8edd 66
tttogasawara 0:99b50c8f8edd 67 // Enable DAC clock
tttogasawara 0:99b50c8f8edd 68 if (obj->dac == DAC_1) {
tttogasawara 0:99b50c8f8edd 69 __DAC1_CLK_ENABLE();
tttogasawara 0:99b50c8f8edd 70 }
tttogasawara 0:99b50c8f8edd 71 #if defined(DAC2)
tttogasawara 0:99b50c8f8edd 72 if (obj->dac == DAC_2) {
tttogasawara 0:99b50c8f8edd 73 __DAC2_CLK_ENABLE();
tttogasawara 0:99b50c8f8edd 74 }
tttogasawara 0:99b50c8f8edd 75 #endif
tttogasawara 0:99b50c8f8edd 76
tttogasawara 0:99b50c8f8edd 77 // Configure DAC
tttogasawara 0:99b50c8f8edd 78 if (obj->dac == DAC_1) {
tttogasawara 0:99b50c8f8edd 79 DacHandle1.Instance = (DAC_TypeDef *)(obj->dac);
tttogasawara 0:99b50c8f8edd 80 } else {
tttogasawara 0:99b50c8f8edd 81 DacHandle2.Instance = (DAC_TypeDef *)(obj->dac);
tttogasawara 0:99b50c8f8edd 82 }
tttogasawara 0:99b50c8f8edd 83
tttogasawara 0:99b50c8f8edd 84 sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
tttogasawara 0:99b50c8f8edd 85 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
tttogasawara 0:99b50c8f8edd 86 sConfig.DAC_OutputSwitch = DAC_OUTPUTSWITCH_ENABLE;
tttogasawara 0:99b50c8f8edd 87
tttogasawara 0:99b50c8f8edd 88 if (pin == PA_4) {
tttogasawara 0:99b50c8f8edd 89 HAL_DAC_ConfigChannel(&DacHandle1, &sConfig, DAC_CHANNEL_1);
tttogasawara 0:99b50c8f8edd 90 pa4_used = 1;
tttogasawara 0:99b50c8f8edd 91 }
tttogasawara 0:99b50c8f8edd 92
tttogasawara 0:99b50c8f8edd 93 #if defined(DAC_CHANNEL_2)
tttogasawara 0:99b50c8f8edd 94 if (pin == PA_5) {
tttogasawara 0:99b50c8f8edd 95 HAL_DAC_ConfigChannel(&DacHandle1, &sConfig, DAC_CHANNEL_2);
tttogasawara 0:99b50c8f8edd 96 pa5_used = 1;
tttogasawara 0:99b50c8f8edd 97 }
tttogasawara 0:99b50c8f8edd 98 #endif
tttogasawara 0:99b50c8f8edd 99
tttogasawara 0:99b50c8f8edd 100 if (pin == PA_6) {
tttogasawara 0:99b50c8f8edd 101 HAL_DAC_ConfigChannel(&DacHandle2, &sConfig, DAC_CHANNEL_1);
tttogasawara 0:99b50c8f8edd 102 }
tttogasawara 0:99b50c8f8edd 103
tttogasawara 0:99b50c8f8edd 104 analogout_write_u16(obj, 0);
tttogasawara 0:99b50c8f8edd 105 }
tttogasawara 0:99b50c8f8edd 106
tttogasawara 0:99b50c8f8edd 107 void analogout_free(dac_t *obj)
tttogasawara 0:99b50c8f8edd 108 {
tttogasawara 0:99b50c8f8edd 109 // Reset DAC and disable clock
tttogasawara 0:99b50c8f8edd 110 if (obj->pin == PA_4) pa4_used = 0;
tttogasawara 0:99b50c8f8edd 111 if (obj->pin == PA_5) pa5_used = 0;
tttogasawara 0:99b50c8f8edd 112
tttogasawara 0:99b50c8f8edd 113 if ((pa4_used == 0) && (pa5_used == 0)) {
tttogasawara 0:99b50c8f8edd 114 __DAC1_FORCE_RESET();
tttogasawara 0:99b50c8f8edd 115 __DAC1_RELEASE_RESET();
tttogasawara 0:99b50c8f8edd 116 __DAC1_CLK_DISABLE();
tttogasawara 0:99b50c8f8edd 117 }
tttogasawara 0:99b50c8f8edd 118
tttogasawara 0:99b50c8f8edd 119 #if defined(DAC2)
tttogasawara 0:99b50c8f8edd 120 if (obj->pin == PA_6) {
tttogasawara 0:99b50c8f8edd 121 __DAC2_FORCE_RESET();
tttogasawara 0:99b50c8f8edd 122 __DAC2_RELEASE_RESET();
tttogasawara 0:99b50c8f8edd 123 __DAC2_CLK_DISABLE();
tttogasawara 0:99b50c8f8edd 124 }
tttogasawara 0:99b50c8f8edd 125 #endif
tttogasawara 0:99b50c8f8edd 126
tttogasawara 0:99b50c8f8edd 127 // Configure GPIO
tttogasawara 0:99b50c8f8edd 128 pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
tttogasawara 0:99b50c8f8edd 129 }
tttogasawara 0:99b50c8f8edd 130
tttogasawara 0:99b50c8f8edd 131 static inline void dac_write(dac_t *obj, int value)
tttogasawara 0:99b50c8f8edd 132 {
tttogasawara 0:99b50c8f8edd 133 if (obj->channel == 1) {
tttogasawara 0:99b50c8f8edd 134 if (obj->dac == DAC_1 ) {
tttogasawara 0:99b50c8f8edd 135 HAL_DAC_SetValue(&DacHandle1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
tttogasawara 0:99b50c8f8edd 136 HAL_DAC_Start(&DacHandle1, DAC_CHANNEL_1);
tttogasawara 0:99b50c8f8edd 137 } else {
tttogasawara 0:99b50c8f8edd 138 HAL_DAC_SetValue(&DacHandle2, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
tttogasawara 0:99b50c8f8edd 139 HAL_DAC_Start(&DacHandle2, DAC_CHANNEL_1);
tttogasawara 0:99b50c8f8edd 140 }
tttogasawara 0:99b50c8f8edd 141
tttogasawara 0:99b50c8f8edd 142 }
tttogasawara 0:99b50c8f8edd 143 #if defined(DAC_CHANNEL_2)
tttogasawara 0:99b50c8f8edd 144 if (obj->channel == 2) {
tttogasawara 0:99b50c8f8edd 145 HAL_DAC_SetValue(&DacHandle1, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
tttogasawara 0:99b50c8f8edd 146 HAL_DAC_Start(&DacHandle1, DAC_CHANNEL_2);
tttogasawara 0:99b50c8f8edd 147 }
tttogasawara 0:99b50c8f8edd 148 #endif
tttogasawara 0:99b50c8f8edd 149 }
tttogasawara 0:99b50c8f8edd 150
tttogasawara 0:99b50c8f8edd 151 static inline int dac_read(dac_t *obj)
tttogasawara 0:99b50c8f8edd 152 {
tttogasawara 0:99b50c8f8edd 153 if (obj->channel == 1) {
tttogasawara 0:99b50c8f8edd 154 if (obj->dac == DAC_1) {
tttogasawara 0:99b50c8f8edd 155 return (int)HAL_DAC_GetValue(&DacHandle1, DAC_CHANNEL_1);
tttogasawara 0:99b50c8f8edd 156 } else {
tttogasawara 0:99b50c8f8edd 157 return (int)HAL_DAC_GetValue(&DacHandle2, DAC_CHANNEL_1);
tttogasawara 0:99b50c8f8edd 158 }
tttogasawara 0:99b50c8f8edd 159
tttogasawara 0:99b50c8f8edd 160 }
tttogasawara 0:99b50c8f8edd 161 #if defined(DAC_CHANNEL_2)
tttogasawara 0:99b50c8f8edd 162 if (obj->channel == 2) {
tttogasawara 0:99b50c8f8edd 163 return (int)HAL_DAC_GetValue(&DacHandle1, DAC_CHANNEL_2);
tttogasawara 0:99b50c8f8edd 164 }
tttogasawara 0:99b50c8f8edd 165 #endif
tttogasawara 0:99b50c8f8edd 166 return 0;
tttogasawara 0:99b50c8f8edd 167 }
tttogasawara 0:99b50c8f8edd 168
tttogasawara 0:99b50c8f8edd 169 void analogout_write(dac_t *obj, float value)
tttogasawara 0:99b50c8f8edd 170 {
tttogasawara 0:99b50c8f8edd 171 if (value < 0.0f) {
tttogasawara 0:99b50c8f8edd 172 dac_write(obj, 0); // Min value
tttogasawara 0:99b50c8f8edd 173 } else if (value > 1.0f) {
tttogasawara 0:99b50c8f8edd 174 dac_write(obj, (int)DAC_RANGE); // Max value
tttogasawara 0:99b50c8f8edd 175 } else {
tttogasawara 0:99b50c8f8edd 176 dac_write(obj, (int)(value * (float)DAC_RANGE));
tttogasawara 0:99b50c8f8edd 177 }
tttogasawara 0:99b50c8f8edd 178 }
tttogasawara 0:99b50c8f8edd 179
tttogasawara 0:99b50c8f8edd 180 void analogout_write_u16(dac_t *obj, uint16_t value)
tttogasawara 0:99b50c8f8edd 181 {
tttogasawara 0:99b50c8f8edd 182 dac_write(obj, value >> (16 - DAC_NB_BITS));
tttogasawara 0:99b50c8f8edd 183 }
tttogasawara 0:99b50c8f8edd 184
tttogasawara 0:99b50c8f8edd 185 float analogout_read(dac_t *obj)
tttogasawara 0:99b50c8f8edd 186 {
tttogasawara 0:99b50c8f8edd 187 uint32_t value = dac_read(obj);
tttogasawara 0:99b50c8f8edd 188 return (float)value * (1.0f / (float)DAC_RANGE);
tttogasawara 0:99b50c8f8edd 189 }
tttogasawara 0:99b50c8f8edd 190
tttogasawara 0:99b50c8f8edd 191 uint16_t analogout_read_u16(dac_t *obj)
tttogasawara 0:99b50c8f8edd 192 {
tttogasawara 0:99b50c8f8edd 193 uint32_t value = dac_read(obj);
tttogasawara 0:99b50c8f8edd 194 return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
tttogasawara 0:99b50c8f8edd 195 }
tttogasawara 0:99b50c8f8edd 196
tttogasawara 0:99b50c8f8edd 197 #endif // DEVICE_ANALOGOUT