mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			STM32: analog_out: generalize code for multiple instance handling
Moving some code in common to be able to manage several ADC instances, or several channels of an instance. The change involves: - moving dac_s structure definition to common_object.h - create TARGET_STM/analogout_api.c and move fully common analog_out functions in there - rename analogout_api.c of each target family into analogout_device.c to keep platform specific code - update analogout_device.c to rely on obj->handle and obj->channel - align analogout_init function as much as possible between families in analogout_device.c filespull/4529/head
							parent
							
								
									b51d676dc0
								
							
						
					
					
						commit
						024b3da5f1
					
				| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,11 +35,6 @@
 | 
			
		|||
#include "mbed_error.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
static DAC_HandleTypeDef DacHandle;
 | 
			
		||||
 | 
			
		||||
void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		||||
    DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +45,20 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    // Get the pin function and assign the used channel to the object
 | 
			
		||||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
    obj->channel = STM_PIN_CHANNEL(function);
 | 
			
		||||
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure GPIO
 | 
			
		||||
    pinmap_pinout(pin, PinMap_DAC);
 | 
			
		||||
| 
						 | 
				
			
			@ -62,15 +70,16 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    __HAL_RCC_DAC1_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    // Configure DAC
 | 
			
		||||
    DacHandle.Instance = (DAC_TypeDef *)(obj->dac);
 | 
			
		||||
    obj->handle.Instance = (DAC_TypeDef *)(obj->dac);
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_Trigger      = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
 | 
			
		||||
    if (pin == PA_4) {
 | 
			
		||||
        HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1);
 | 
			
		||||
    } else { // PA_5
 | 
			
		||||
        HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_2);
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_ConfigChannel failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -86,53 +95,4 @@ void analogout_free(dac_t *obj) {
 | 
			
		|||
    pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    }
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    }
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +113,15 @@ struct i2c_s {
 | 
			
		|||
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_ANALOGOUT
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,16 +35,9 @@
 | 
			
		|||
#include "stm32f2xx_hal.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE    (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
DAC_HandleTypeDef    DacHandle;
 | 
			
		||||
static DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
void analogout_init(dac_t *obj, PinName pin)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t channel ;
 | 
			
		||||
    HAL_StatusTypeDef status;
 | 
			
		||||
    DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
    // Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
 | 
			
		||||
    obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +45,19 @@ void analogout_init(dac_t *obj, PinName pin)
 | 
			
		|||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
    // Save the channel for the write and read functions
 | 
			
		||||
    obj->channel = STM_PIN_CHANNEL(function);
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (obj->dac == (DACName)NC) {
 | 
			
		||||
        error("DAC pin mapping failed");
 | 
			
		||||
| 
						 | 
				
			
			@ -65,91 +70,25 @@ void analogout_init(dac_t *obj, PinName pin)
 | 
			
		|||
 | 
			
		||||
    __DAC_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    DacHandle.Instance = DAC;
 | 
			
		||||
 | 
			
		||||
    status = HAL_DAC_Init(&DacHandle);
 | 
			
		||||
    if (status != HAL_OK) {
 | 
			
		||||
    obj->handle.Instance = DAC;
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        channel = DAC_CHANNEL_1;
 | 
			
		||||
    } else {
 | 
			
		||||
        channel = DAC_CHANNEL_2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, channel) != HAL_OK) {
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_ConfigChannel failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_Start(&DacHandle, channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_Start failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_SetValue(&DacHandle, channel, DAC_ALIGN_12B_R, 0x000) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_SetValue failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_free(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value)
 | 
			
		||||
{
 | 
			
		||||
    HAL_StatusTypeDef status = HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    } else if (obj->channel == 2) {
 | 
			
		||||
        status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (status != HAL_OK) {
 | 
			
		||||
        error("DAC pin mapping failed");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    } else if (obj->channel == 2) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;   /* Just silented warning */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value)
 | 
			
		||||
{
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value)
 | 
			
		||||
{
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +63,7 @@ struct analogin_s {
 | 
			
		|||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct serial_s {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,13 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,13 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,12 +61,6 @@ struct analogin_s {
 | 
			
		|||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,13 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,13 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined (DEVICE_CAN)
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,9 +35,6 @@
 | 
			
		|||
#include "mbed_error.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
// These variables are used for the "free" function
 | 
			
		||||
static int pa4_used = 0;
 | 
			
		||||
static int pa5_used = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +50,7 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
 | 
			
		||||
    // Save the channel for the write and read functions
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
| 
						 | 
				
			
			@ -85,13 +83,16 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
 | 
			
		||||
    // Configure DAC
 | 
			
		||||
    obj->handle.Instance = (DAC_TypeDef *)(obj->dac);
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_Trigger      = DAC_TRIGGER_NONE;
 | 
			
		||||
    /* Enable both Buffer and Switch in the configuration,
 | 
			
		||||
     * letting HAL layer in charge of selecting either one
 | 
			
		||||
     * or the other depending on the actual DAC instance and
 | 
			
		||||
     * channel being configured.
 | 
			
		||||
     */
 | 
			
		||||
    sConfig.DAC_Trigger      = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
#if defined(DAC_OUTPUTSWITCH_ENABLE)
 | 
			
		||||
    sConfig.DAC_OutputSwitch = DAC_OUTPUTSWITCH_ENABLE;
 | 
			
		||||
| 
						 | 
				
			
			@ -101,13 +102,13 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
        pa4_used = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (pin == PA_5) {
 | 
			
		||||
        pa5_used = 1;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel);
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_ConfigChannel failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -135,37 +136,4 @@ void analogout_free(dac_t *obj) {
 | 
			
		|||
    pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    HAL_DAC_SetValue(&obj->handle, obj->channel, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    HAL_DAC_Start(&obj->handle, obj->channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    return (int)HAL_DAC_GetValue(&obj->handle, obj->channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -111,6 +111,13 @@ struct i2c_s {
 | 
			
		|||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct trng_s {
 | 
			
		||||
    RNG_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,11 +64,6 @@ struct trng_s {
 | 
			
		|||
    RNG_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,23 +35,29 @@
 | 
			
		|||
#include "stm32f4xx_hal.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE    (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
DAC_HandleTypeDef    DacHandle;
 | 
			
		||||
static DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		||||
    uint32_t channel ;
 | 
			
		||||
    HAL_StatusTypeDef status;
 | 
			
		||||
    DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
    // Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
 | 
			
		||||
    obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
 | 
			
		||||
    // Get the functions (dac channel) from the pin and assign it to the object
 | 
			
		||||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
 | 
			
		||||
    // Save the channel for the write and read functions
 | 
			
		||||
    obj->channel = STM_PIN_CHANNEL(function);
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (obj->dac == (DACName)NC) {
 | 
			
		||||
        error("DAC pin mapping failed");
 | 
			
		||||
| 
						 | 
				
			
			@ -64,84 +70,22 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
 | 
			
		||||
    __HAL_RCC_DAC_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    DacHandle.Instance = DAC;
 | 
			
		||||
 | 
			
		||||
    status = HAL_DAC_Init(&DacHandle);
 | 
			
		||||
    if ( status != HAL_OK ) {
 | 
			
		||||
    obj->handle.Instance = DAC;
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        channel = DAC_CHANNEL_1; 
 | 
			
		||||
    } else {
 | 
			
		||||
        channel = DAC_CHANNEL_2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, channel) != HAL_OK) {
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_ConfigChannel failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_Start(&DacHandle, channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_Start failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_SetValue(&DacHandle, channel, DAC_ALIGN_12B_R, 0x000) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_SetValue failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_free(dac_t *obj) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    HAL_StatusTypeDef status = HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    } else if (obj->channel == 2) {
 | 
			
		||||
        status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( status != HAL_OK ) {
 | 
			
		||||
        error("DAC pin mapping failed");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    } else if (obj->channel == 2) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
	return 0;	/* Just silented warning */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +113,14 @@ struct i2c_s {
 | 
			
		|||
#define GPIO_IP_WITHOUT_BRR
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_ANALOGOUT
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint8_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,23 +35,29 @@
 | 
			
		|||
#include "stm32f7xx_hal.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE    (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
DAC_HandleTypeDef    DacHandle;
 | 
			
		||||
static DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		||||
    uint32_t channel ;
 | 
			
		||||
    HAL_StatusTypeDef status;
 | 
			
		||||
    DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
    // Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
 | 
			
		||||
    obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
 | 
			
		||||
    // Get the functions (dac channel) from the pin and assign it to the object
 | 
			
		||||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
 | 
			
		||||
    // Save the channel for the write and read functions
 | 
			
		||||
    obj->channel = STM_PIN_CHANNEL(function);
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (obj->dac == (DACName)NC) {
 | 
			
		||||
        error("DAC pin mapping failed");
 | 
			
		||||
| 
						 | 
				
			
			@ -64,84 +70,23 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
 | 
			
		||||
    __DAC_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    DacHandle.Instance = DAC;
 | 
			
		||||
 | 
			
		||||
    status = HAL_DAC_Init(&DacHandle);
 | 
			
		||||
    if (status != HAL_OK) {
 | 
			
		||||
    obj->handle.Instance = DAC;
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        channel = DAC_CHANNEL_1;
 | 
			
		||||
    } else {
 | 
			
		||||
        channel = DAC_CHANNEL_2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, channel) != HAL_OK) {
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_ConfigChannel failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_Start(&DacHandle, channel) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_Start failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_SetValue(&DacHandle, channel, DAC_ALIGN_12B_R, 0x000) != HAL_OK) {
 | 
			
		||||
        error("HAL_DAC_SetValue failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_free(dac_t *obj) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    HAL_StatusTypeDef status = HAL_ERROR;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    } else if (obj->channel == 2) {
 | 
			
		||||
        status = HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (status != HAL_OK) {
 | 
			
		||||
        error("DAC pin mapping failed");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    } else if (obj->channel == 2) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;   /* Just silented warning */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +114,13 @@ struct i2c_s {
 | 
			
		|||
#define GPIO_IP_WITHOUT_BRR
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct trng_s {
 | 
			
		||||
    RNG_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct trng_s {
 | 
			
		||||
    RNG_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct trng_s {
 | 
			
		||||
    RNG_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,11 +35,6 @@
 | 
			
		|||
#include "mbed_error.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
static DAC_HandleTypeDef DacHandle;
 | 
			
		||||
 | 
			
		||||
// These variables are used for the "free" function
 | 
			
		||||
static int channel1_used = 0;
 | 
			
		||||
static int channel2_used = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +49,19 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    // Get the pin function and assign the used channel to the object
 | 
			
		||||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
    obj->channel = STM_PIN_CHANNEL(function);
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure GPIO
 | 
			
		||||
    pinmap_pinout(pin, PinMap_DAC);
 | 
			
		||||
| 
						 | 
				
			
			@ -66,26 +73,22 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    __DAC_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    // Configure DAC
 | 
			
		||||
    DacHandle.Instance = DAC;
 | 
			
		||||
    obj->handle.Instance = DAC;
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_Trigger      = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_2) != HAL_OK) {
 | 
			
		||||
            error("Cannot configure DAC channel 2");
 | 
			
		||||
        }
 | 
			
		||||
        channel2_used = 1;
 | 
			
		||||
    } else
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        // channel 1 per default
 | 
			
		||||
        if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1) != HAL_OK) {
 | 
			
		||||
            error("Cannot configure DAC channel 1");
 | 
			
		||||
        }
 | 
			
		||||
        obj->channel = 1;
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("Cannot configure DAC channel 2");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == DAC_CHANNEL_1) {
 | 
			
		||||
        channel1_used = 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        channel2_used = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -93,9 +96,10 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
 | 
			
		||||
void analogout_free(dac_t *obj) {
 | 
			
		||||
    // Reset DAC and disable clock
 | 
			
		||||
    if (obj->channel == 1) channel1_used = 0;
 | 
			
		||||
    if (obj->channel == 2) channel2_used = 0;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == DAC_CHANNEL_1) channel1_used = 0;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == DAC_CHANNEL_2) channel2_used = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    if ((channel1_used == 0) && (channel2_used == 0)) {
 | 
			
		||||
        __DAC_FORCE_RESET();
 | 
			
		||||
        __DAC_RELEASE_RESET();
 | 
			
		||||
| 
						 | 
				
			
			@ -106,53 +110,4 @@ void analogout_free(dac_t *obj) {
 | 
			
		|||
    pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    }
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    }
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +118,15 @@ struct flash_s {
 | 
			
		|||
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_ANALOGOUT
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,8 +67,8 @@ const PinMap PinMap_ADC[] = {
 | 
			
		|||
//*** DAC ***
 | 
			
		||||
 | 
			
		||||
const PinMap PinMap_DAC[] = {
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC1_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC1_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {NC,   NC,    0}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GPIO_IP_WITHOUT_BRR
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,8 +67,8 @@ const PinMap PinMap_ADC[] = {
 | 
			
		|||
//*** DAC ***
 | 
			
		||||
 | 
			
		||||
const PinMap PinMap_DAC[] = {
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC1_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC1_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {NC,   NC,    0}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,8 +67,8 @@ const PinMap PinMap_ADC[] = {
 | 
			
		|||
//*** DAC ***
 | 
			
		||||
 | 
			
		||||
const PinMap PinMap_DAC[] = {
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC1_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC1_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {NC,   NC,    0}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,8 +57,8 @@ const PinMap PinMap_ADC[] = {
 | 
			
		|||
//*** DAC ***
 | 
			
		||||
 | 
			
		||||
const PinMap PinMap_DAC[] = {
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // DAC_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {PA_4, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 1, 0)}, // DAC1_OUT1
 | 
			
		||||
    {PA_5, DAC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 2, 0)}, // DAC1_OUT2 (Warning: LED1 is also on this pin)
 | 
			
		||||
    {NC,   NC,    0}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,11 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GPIO_IP_WITHOUT_BRR
 | 
			
		||||
#include "common_objects.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,11 +35,6 @@
 | 
			
		|||
#include "mbed_error.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
static DAC_HandleTypeDef DacHandle;
 | 
			
		||||
 | 
			
		||||
// These variables are used for the "free" function
 | 
			
		||||
static int pa4_used = 0;
 | 
			
		||||
static int pa5_used = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,11 +42,24 @@ static int pa5_used = 0;
 | 
			
		|||
void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		||||
    DAC_ChannelConfTypeDef sConfig;
 | 
			
		||||
 | 
			
		||||
    DacHandle.Instance = DAC;
 | 
			
		||||
 | 
			
		||||
    // Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
 | 
			
		||||
    obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(obj->dac != (DACName)NC);
 | 
			
		||||
    // Get the pin function and assign the used channel to the object
 | 
			
		||||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure GPIO
 | 
			
		||||
    pinmap_pinout(pin, PinMap_DAC);
 | 
			
		||||
| 
						 | 
				
			
			@ -59,21 +67,28 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    // Save the channel for future use
 | 
			
		||||
    obj->pin = pin;
 | 
			
		||||
 | 
			
		||||
    obj->handle.Instance = DAC;
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Enable DAC clock
 | 
			
		||||
    __DAC_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    // Configure DAC
 | 
			
		||||
    sConfig.DAC_Trigger      = DAC_TRIGGER_NONE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
 | 
			
		||||
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 | 
			
		||||
 | 
			
		||||
    if (pin == PA_4) {
 | 
			
		||||
        HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1);
 | 
			
		||||
        pa4_used = 1;
 | 
			
		||||
    } else { // PA_5
 | 
			
		||||
        HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_2);
 | 
			
		||||
        pa5_used = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("Cannot configure DAC channel\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,46 +106,4 @@ void analogout_free(dac_t *obj) {
 | 
			
		|||
    pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    if (obj->pin == PA_4) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    } else { // PA_5
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    if (obj->pin == PA_4) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    } else { // PA_5
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ struct pwmout_s {
 | 
			
		|||
    uint32_t period;
 | 
			
		||||
    uint32_t pulse;
 | 
			
		||||
    uint8_t channel;
 | 
			
		||||
    uint8_t inverted; 
 | 
			
		||||
    uint8_t inverted;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct serial_s {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,13 @@ struct i2c_s {
 | 
			
		|||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,12 +60,6 @@ struct analogin_s {
 | 
			
		|||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct can_s {
 | 
			
		||||
    CANName can;
 | 
			
		||||
    int index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,11 +35,6 @@
 | 
			
		|||
#include "mbed_error.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
static DAC_HandleTypeDef DacHandle;
 | 
			
		||||
 | 
			
		||||
// These variables are used for the "free" function
 | 
			
		||||
static int channel1_used = 0;
 | 
			
		||||
static int channel2_used = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +49,20 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    // Get the pin function and assign the used channel to the object
 | 
			
		||||
    uint32_t function = pinmap_function(pin, PinMap_DAC);
 | 
			
		||||
    MBED_ASSERT(function != (uint32_t)NC);
 | 
			
		||||
    obj->channel = STM_PIN_CHANNEL(function);
 | 
			
		||||
 | 
			
		||||
    switch (STM_PIN_CHANNEL(function)) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_1;
 | 
			
		||||
            break;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
        case 2:
 | 
			
		||||
            obj->channel = DAC_CHANNEL_2;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            error("Unknown DAC channel");
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure GPIO
 | 
			
		||||
    pinmap_pinout(pin, PinMap_DAC);
 | 
			
		||||
| 
						 | 
				
			
			@ -66,10 +74,9 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    __HAL_RCC_DAC1_CLK_ENABLE();
 | 
			
		||||
 | 
			
		||||
    // Configure DAC
 | 
			
		||||
    DacHandle.Instance = DAC;
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_Init(&DacHandle) != HAL_OK) {
 | 
			
		||||
        error("Cannot initialize DAC\n");
 | 
			
		||||
    obj->handle.Instance = DAC;
 | 
			
		||||
    if (HAL_DAC_Init(&obj->handle) != HAL_OK ) {
 | 
			
		||||
        error("HAL_DAC_Init failed");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,17 +85,14 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
    sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
 | 
			
		||||
    sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
 | 
			
		||||
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_2) != HAL_OK) {
 | 
			
		||||
            error("Cannot configure DAC channel 2\n");
 | 
			
		||||
        }
 | 
			
		||||
        channel2_used = 1;
 | 
			
		||||
    } else { // channel 1 per default
 | 
			
		||||
        if (HAL_DAC_ConfigChannel(&DacHandle, &sConfig, DAC_CHANNEL_1) != HAL_OK) {
 | 
			
		||||
            error("Cannot configure DAC channel 1\n");
 | 
			
		||||
        }
 | 
			
		||||
        obj->channel = 1;
 | 
			
		||||
    if (obj->channel == DAC_CHANNEL_1) {
 | 
			
		||||
        channel1_used = 1;
 | 
			
		||||
    } else { // channel 1 per default
 | 
			
		||||
        channel2_used = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
 | 
			
		||||
        error("Cannot configure DAC channel\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    analogout_write_u16(obj, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -96,8 +100,10 @@ void analogout_init(dac_t *obj, PinName pin) {
 | 
			
		|||
 | 
			
		||||
void analogout_free(dac_t *obj) {
 | 
			
		||||
    // Reset DAC and disable clock
 | 
			
		||||
    if (obj->channel == 1) channel1_used = 0;
 | 
			
		||||
    if (obj->channel == 2) channel2_used = 0;
 | 
			
		||||
    if (obj->channel == DAC_CHANNEL_1) channel1_used = 0;
 | 
			
		||||
#if defined(DAC_CHANNEL_2)
 | 
			
		||||
    if (obj->channel == DAC_CHANNEL_2) channel2_used = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if ((channel1_used == 0) && (channel2_used == 0)) {
 | 
			
		||||
        __HAL_RCC_DAC1_FORCE_RESET();
 | 
			
		||||
| 
						 | 
				
			
			@ -109,49 +115,4 @@ void analogout_free(dac_t *obj) {
 | 
			
		|||
    pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    }
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
        HAL_DAC_Start(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj) {
 | 
			
		||||
    if (obj->channel == 1) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_1);
 | 
			
		||||
    }
 | 
			
		||||
    if (obj->channel == 2) {
 | 
			
		||||
        return (int)HAL_DAC_GetValue(&DacHandle, DAC_CHANNEL_2);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value) {
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value) {
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj) {
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +118,13 @@ struct flash_s {
 | 
			
		|||
 | 
			
		||||
#include "gpio_object.h"
 | 
			
		||||
 | 
			
		||||
struct dac_s {
 | 
			
		||||
    DACName dac;
 | 
			
		||||
    PinName pin;
 | 
			
		||||
    uint32_t channel;
 | 
			
		||||
    DAC_HandleTypeDef handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
/* mbed Microcontroller Library
 | 
			
		||||
 * Copyright (c) 2017, STMicroelectronics
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of STMicroelectronics nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | 
			
		||||
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
			
		||||
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "analogout_api.h"
 | 
			
		||||
 | 
			
		||||
#if DEVICE_ANALOGOUT
 | 
			
		||||
 | 
			
		||||
#include "cmsis.h"
 | 
			
		||||
#include "pinmap.h"
 | 
			
		||||
#include "mbed_error.h"
 | 
			
		||||
#include "PeripheralPins.h"
 | 
			
		||||
 | 
			
		||||
#define DAC_RANGE (0xFFF) // 12 bits
 | 
			
		||||
#define DAC_NB_BITS  (12)
 | 
			
		||||
 | 
			
		||||
static inline void dac_write(dac_t *obj, int value)
 | 
			
		||||
{
 | 
			
		||||
    HAL_DAC_SetValue(&obj->handle, obj->channel, DAC_ALIGN_12B_R, (value & DAC_RANGE));
 | 
			
		||||
    HAL_DAC_Start(&obj->handle, obj->channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline int dac_read(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
    return (int)HAL_DAC_GetValue(&obj->handle, obj->channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write(dac_t *obj, float value)
 | 
			
		||||
{
 | 
			
		||||
    if (value < 0.0f) {
 | 
			
		||||
        dac_write(obj, 0); // Min value
 | 
			
		||||
    } else if (value > 1.0f) {
 | 
			
		||||
        dac_write(obj, (int)DAC_RANGE); // Max value
 | 
			
		||||
    } else {
 | 
			
		||||
        dac_write(obj, (int)(value * (float)DAC_RANGE));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void analogout_write_u16(dac_t *obj, uint16_t value)
 | 
			
		||||
{
 | 
			
		||||
    dac_write(obj, value >> (16 - DAC_NB_BITS));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float analogout_read(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (float)value * (1.0f / (float)DAC_RANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t analogout_read_u16(dac_t *obj)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t value = dac_read(obj);
 | 
			
		||||
    return (value << 4) | ((value >> 8) & 0x000F); // Conversion from 12 to 16 bits
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // DEVICE_ANALOGOUT
 | 
			
		||||
		Loading…
	
		Reference in New Issue