Skip to content

Manage multiple instances of analog out #4529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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
9 changes: 9 additions & 0 deletions targets/TARGET_STM/TARGET_STM32F0/common_objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,29 @@
#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);
// 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");
Expand All @@ -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
1 change: 1 addition & 0 deletions targets/TARGET_STM/TARGET_STM32F2/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct analogin_s {
struct dac_s {
DACName dac;
uint8_t channel;
DAC_HandleTypeDef handle;
};

struct serial_s {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,7 @@ struct analogin_s {
ADCName adc;
PinName pin;
uint32_t channel;
};

struct dac_s {
DACName dac;
PinName pin;
uint32_t channel;
DAC_HandleTypeDef handle;
};

struct can_s {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@ struct analogin_s {
uint32_t channel;
};

struct dac_s {
DACName dac;
PinName pin;
uint32_t channel;
};

#if defined (DEVICE_CAN)
struct can_s {
CANName can;
Expand Down
Loading