Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Luiz Fernando Lavado Villa
Core
Commits
2615d168
Commit
2615d168
authored
Jul 16, 2021
by
Clément Foucher
Browse files
Add DAC driver module.
parent
9b4653fc
Changes
9
Hide whitespace changes
Inline
Side-by-side
zephyr/modules/owntech_dac_driver/zephyr/CMakeLists.txt
0 → 100644
View file @
2615d168
if
(
CONFIG_OWNTECH_DAC_DRIVER
)
# Select directory to add to the include path
zephyr_include_directories
(
./public_include
)
# Define the current folder as a Zephyr library
zephyr_library
()
# Select source files to be compiled
zephyr_library_sources
(
./src/stm32_dac_driver.c
./src/owntech_dac_configure.c
)
endif
()
zephyr/modules/owntech_dac_driver/zephyr/Kconfig
0 → 100644
View file @
2615d168
config OWNTECH_DAC_DRIVER
bool "Enable OwnTech DAC driver"
default y
zephyr/modules/owntech_dac_driver/zephyr/module.yml
0 → 100644
View file @
2615d168
name
:
owntech_dac_driver
build
:
cmake
:
zephyr
kconfig
:
zephyr/Kconfig
zephyr/modules/owntech_dac_driver/zephyr/public_include/dac.h
0 → 100644
View file @
2615d168
/*
* Copyright (c) 2021 LAAS-CNRS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGLPV2.1
*/
/**
* @author Clément Foucher <clement.foucher@laas.fr>
*/
#ifndef DAC_H_
#define DAC_H_
// Zephyr
#include
<zephyr.h>
#include
<device.h>
#ifdef __cplusplus
extern
"C"
{
#endif
// Configuration types
typedef
enum
{
dac_function_noise
,
dac_function_triangle
,
dac_function_sawtooth
}
dac_function_t
;
typedef
struct
{
dac_function_t
dac_function
;
uint32_t
trigger_source
;
uint32_t
step_trigger_source
;
uint32_t
polarity
;
uint32_t
reset_data
;
uint32_t
step_data
;
}
dac_function_config_t
;
typedef
struct
{
uint32_t
pin_connect
;
uint32_t
pin_buffer_enable
;
}
dac_pin_config_t
;
// API
typedef
void
(
*
dac_api_setconstvalue
)
(
const
struct
device
*
dev
,
uint8_t
channel
,
uint32_t
value
);
typedef
void
(
*
dac_api_setfunction
)
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_function_config_t
*
config
);
typedef
void
(
*
dac_api_pinconfigure
)
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_pin_config_t
*
config
);
typedef
void
(
*
dac_api_start
)
(
const
struct
device
*
dev
,
uint8_t
channel
);
typedef
void
(
*
dac_api_stop
)
(
const
struct
device
*
dev
,
uint8_t
channel
);
__subsystem
struct
dac_driver_api
{
dac_api_setconstvalue
setconstvalue
;
dac_api_setfunction
setfunction
;
dac_api_pinconfigure
pinconfigure
;
dac_api_start
start
;
dac_api_stop
stop
;
};
static
inline
void
dac_set_const_value
(
const
struct
device
*
dev
,
uint8_t
channel
,
uint32_t
value
)
{
const
struct
dac_driver_api
*
api
=
(
const
struct
dac_driver_api
*
)(
dev
->
api
);
api
->
setconstvalue
(
dev
,
channel
,
value
);
}
static
inline
void
dac_set_function
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_function_config_t
*
function_config
)
{
const
struct
dac_driver_api
*
api
=
(
const
struct
dac_driver_api
*
)(
dev
->
api
);
api
->
setfunction
(
dev
,
channel
,
function_config
);
}
static
inline
void
dac_pin_configure
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_pin_config_t
*
pin_config
)
{
const
struct
dac_driver_api
*
api
=
(
const
struct
dac_driver_api
*
)(
dev
->
api
);
api
->
pinconfigure
(
dev
,
channel
,
pin_config
);
}
static
inline
void
dac_start
(
const
struct
device
*
dev
,
uint8_t
channel
)
{
const
struct
dac_driver_api
*
api
=
(
const
struct
dac_driver_api
*
)(
dev
->
api
);
api
->
start
(
dev
,
channel
);
}
static
inline
void
dac_stop
(
const
struct
device
*
dev
,
uint8_t
channel
)
{
const
struct
dac_driver_api
*
api
=
(
const
struct
dac_driver_api
*
)(
dev
->
api
);
api
->
stop
(
dev
,
channel
);
}
/////
// Owntech-specific config
#define DAC1_LABEL DT_PROP(DT_NODELABEL(dac1), label)
#define DAC2_LABEL DT_PROP(DT_NODELABEL(dac2), label)
#define DAC3_LABEL DT_PROP(DT_NODELABEL(dac3), label)
void
owntech_dac_dac2_constant_init
();
void
owntech_dac_dac1_dac3_current_mode_init
();
#ifdef __cplusplus
}
#endif
#endif // DAC_H_
zephyr/modules/owntech_dac_driver/zephyr/src/owntech_dac_configure.c
0 → 100644
View file @
2615d168
/*
* Copyright (c) 2021 LAAS-CNRS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGLPV2.1
*/
/**
* @author Clément Foucher <clement.foucher@laas.fr>
*/
// Zephyr
#include
<zephyr.h>
// STM32LL
#include
<stm32_ll_dac.h>
// Owntech driver
#include
"dac.h"
// TODO: this function must *always* be run.
// Write a driver to load on startup without user action?
void
owntech_dac_dac2_constant_init
()
{
const
struct
device
*
dac2
=
device_get_binding
(
DAC2_LABEL
);
dac_pin_config_t
pin_config
=
{
.
pin_connect
=
LL_DAC_OUTPUT_CONNECT_GPIO
,
.
pin_buffer_enable
=
LL_DAC_OUTPUT_BUFFER_ENABLE
};
dac_set_const_value
(
dac2
,
1
,
2048U
);
dac_pin_configure
(
dac2
,
1
,
&
pin_config
);
dac_start
(
dac2
,
1
);
}
void
owntech_dac_dac1_dac3_current_mode_init
()
{
const
struct
device
*
dac1
=
device_get_binding
(
DAC1_LABEL
);
const
struct
device
*
dac3
=
device_get_binding
(
DAC3_LABEL
);
dac_function_config_t
function_config
=
{
.
dac_function
=
dac_function_sawtooth
,
.
trigger_source
=
LL_DAC_TRIG_EXT_HRTIM_RST_TRG1
,
.
step_trigger_source
=
LL_DAC_TRIG_EXT_HRTIM_STEP_TRG1
,
.
polarity
=
LL_DAC_SAWTOOTH_POLARITY_DECREMENT
,
.
reset_data
=
4000
,
.
step_data
=
200
};
dac_pin_config_t
pin_config
=
{
.
pin_connect
=
LL_DAC_OUTPUT_CONNECT_INTERNAL
,
.
pin_buffer_enable
=
LL_DAC_OUTPUT_BUFFER_DISABLE
};
// DAC 1
dac_set_function
(
dac1
,
1
,
&
function_config
);
dac_pin_configure
(
dac1
,
1
,
&
pin_config
);
dac_start
(
dac1
,
1
);
// DAC 3
function_config
.
trigger_source
=
LL_DAC_TRIG_EXT_HRTIM_RST_TRG2
;
function_config
.
step_trigger_source
=
LL_DAC_TRIG_EXT_HRTIM_STEP_TRG2
;
dac_set_function
(
dac3
,
1
,
&
function_config
);
dac_pin_configure
(
dac3
,
1
,
&
pin_config
);
dac_start
(
dac3
,
1
);
}
zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.c
0 → 100644
View file @
2615d168
/*
* Copyright (c) 2021 LAAS-CNRS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGLPV2.1
*/
/**
* @author Clément Foucher <clement.foucher@laas.fr>
*/
// Zephyr
#include
<zephyr.h>
// STM32 LL
#include
<stm32_ll_dac.h>
#include
<stm32_ll_gpio.h>
#include
<stm32_ll_bus.h>
// Current file header
#include
"stm32_dac_driver.h"
/////
// Init function
static
int
dac_stm32_init
(
const
struct
device
*
dev
)
{
DAC_TypeDef
*
dac_dev
=
((
struct
stm32_dac_driver_data
*
)
dev
->
data
)
->
dac_struct
;
if
(
dac_dev
==
DAC1
)
{
LL_AHB2_GRP1_EnableClock
(
LL_AHB2_GRP1_PERIPH_DAC1
);
}
else
if
(
dac_dev
==
DAC2
)
{
LL_AHB2_GRP1_EnableClock
(
LL_AHB2_GRP1_PERIPH_DAC2
);
}
else
if
(
dac_dev
==
DAC3
)
{
LL_AHB2_GRP1_EnableClock
(
LL_AHB2_GRP1_PERIPH_DAC3
);
}
return
0
;
}
/////
// API
static
const
struct
dac_driver_api
dac_funcs
=
{
.
setconstvalue
=
dac_stm32_set_const_value
,
.
setfunction
=
dac_stm32_set_function
,
.
pinconfigure
=
dac_stm32_pin_configure
,
.
start
=
dac_stm32_start
,
.
stop
=
dac_stm32_stop
};
static
void
dac_stm32_set_const_value
(
const
struct
device
*
dev
,
uint8_t
channel
,
uint32_t
value
)
{
struct
stm32_dac_driver_data
*
data
=
(
struct
stm32_dac_driver_data
*
)
dev
->
data
;
DAC_TypeDef
*
dac_dev
=
data
->
dac_struct
;
uint8_t
dac_channel
=
__LL_DAC_DECIMAL_NB_TO_CHANNEL
(
channel
);
if
(
data
->
dac_mode
!=
dac_mode_constant
)
{
data
->
dac_mode
=
dac_mode_constant
;
LL_DAC_SetSignedFormat
(
dac_dev
,
dac_channel
,
LL_DAC_SIGNED_FORMAT_DISABLE
);
LL_DAC_SetWaveAutoGeneration
(
dac_dev
,
dac_channel
,
LL_DAC_WAVE_AUTO_GENERATION_NONE
);
LL_DAC_DisableTrigger
(
dac_dev
,
dac_channel
);
LL_DAC_DisableDMADoubleDataMode
(
dac_dev
,
dac_channel
);
}
LL_DAC_ConvertData12RightAligned
(
dac_dev
,
dac_channel
,
value
);
}
static
void
dac_stm32_set_function
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_function_config_t
*
function_config
)
{
struct
stm32_dac_driver_data
*
data
=
(
struct
stm32_dac_driver_data
*
)
dev
->
data
;
DAC_TypeDef
*
dac_dev
=
data
->
dac_struct
;
uint8_t
dac_channel
=
__LL_DAC_DECIMAL_NB_TO_CHANNEL
(
channel
);
data
->
dac_mode
=
dac_mode_function
;
if
(
function_config
->
dac_function
==
dac_function_sawtooth
)
{
LL_DAC_SetSignedFormat
(
dac_dev
,
dac_channel
,
LL_DAC_SIGNED_FORMAT_DISABLE
);
LL_DAC_SetWaveAutoGeneration
(
dac_dev
,
dac_channel
,
LL_DAC_WAVE_AUTO_GENERATION_SAWTOOTH
);
LL_DAC_SetWaveSawtoothResetTriggerSource
(
dac_dev
,
dac_channel
,
function_config
->
trigger_source
);
LL_DAC_SetWaveSawtoothStepTriggerSource
(
dac_dev
,
dac_channel
,
function_config
->
step_trigger_source
);
LL_DAC_SetWaveSawtoothPolarity
(
dac_dev
,
dac_channel
,
function_config
->
polarity
);
LL_DAC_SetWaveSawtoothResetData
(
dac_dev
,
dac_channel
,
function_config
->
reset_data
);
LL_DAC_SetWaveSawtoothStepData
(
dac_dev
,
dac_channel
,
function_config
->
step_data
);
LL_DAC_EnableTrigger
(
dac_dev
,
dac_channel
);
LL_DAC_DisableDMADoubleDataMode
(
dac_dev
,
dac_channel
);
}
}
static
void
dac_stm32_pin_configure
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_pin_config_t
*
pin_config
)
{
struct
stm32_dac_driver_data
*
data
=
(
struct
stm32_dac_driver_data
*
)
dev
->
data
;
DAC_TypeDef
*
dac_dev
=
data
->
dac_struct
;
uint8_t
dac_channel
=
__LL_DAC_DECIMAL_NB_TO_CHANNEL
(
channel
);
LL_DAC_ConfigOutput
(
dac_dev
,
dac_channel
,
LL_DAC_OUTPUT_MODE_NORMAL
,
pin_config
->
pin_buffer_enable
,
pin_config
->
pin_connect
);
}
static
void
dac_stm32_start
(
const
struct
device
*
dev
,
uint8_t
channel
)
{
struct
stm32_dac_driver_data
*
data
=
(
struct
stm32_dac_driver_data
*
)
dev
->
data
;
DAC_TypeDef
*
dac_dev
=
data
->
dac_struct
;
uint8_t
dac_channel
=
__LL_DAC_DECIMAL_NB_TO_CHANNEL
(
channel
);
LL_DAC_Enable
(
dac_dev
,
dac_channel
);
while
(
LL_DAC_IsReady
(
dac_dev
,
dac_channel
)
==
0
)
{
// Wait
}
}
static
void
dac_stm32_stop
(
const
struct
device
*
dev
,
uint8_t
channel
)
{
struct
stm32_dac_driver_data
*
data
=
(
struct
stm32_dac_driver_data
*
)
dev
->
data
;
DAC_TypeDef
*
dac_dev
=
data
->
dac_struct
;
uint8_t
dac_channel
=
__LL_DAC_DECIMAL_NB_TO_CHANNEL
(
channel
);
LL_DAC_Disable
(
dac_dev
,
dac_channel
);
}
/////
// Device definitions
// DAC 1
#if DT_NODE_HAS_STATUS(DAC1_NODELABEL, okay)
struct
stm32_dac_driver_data
dac1_data
=
{
.
dac_struct
=
DAC1
,
.
dac_mode
=
dac_mode_unset
};
DEVICE_DT_DEFINE
(
DAC1_NODELABEL
,
dac_stm32_init
,
device_pm_control_nop
,
&
dac1_data
,
NULL
,
PRE_KERNEL_1
,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE
,
&
dac_funcs
);
#endif // DAC 1
// DAC 2
#if DT_NODE_HAS_STATUS(DAC2_NODELABEL, okay)
struct
stm32_dac_driver_data
dac2_data
=
{
.
dac_struct
=
DAC2
,
.
dac_mode
=
dac_mode_unset
};
DEVICE_DT_DEFINE
(
DAC2_NODELABEL
,
dac_stm32_init
,
device_pm_control_nop
,
&
dac2_data
,
NULL
,
PRE_KERNEL_1
,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE
,
&
dac_funcs
);
#endif // DAC 2
// DAC 3
#if DT_NODE_HAS_STATUS(DAC3_NODELABEL, okay)
struct
stm32_dac_driver_data
dac3_data
=
{
.
dac_struct
=
DAC3
,
.
dac_mode
=
dac_mode_unset
};
DEVICE_DT_DEFINE
(
DAC3_NODELABEL
,
dac_stm32_init
,
device_pm_control_nop
,
&
dac3_data
,
NULL
,
PRE_KERNEL_1
,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE
,
&
dac_funcs
);
#endif // DAC 3
zephyr/modules/owntech_dac_driver/zephyr/src/stm32_dac_driver.h
0 → 100644
View file @
2615d168
/*
* Copyright (c) 2021 LAAS-CNRS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGLPV2.1
*/
/**
* @author Clément Foucher <clement.foucher@laas.fr>
*/
#ifndef STM32_DAC_DRIVER_H_
#define STM32_DAC_DRIVER_H_
// Zephyr
#include
<device.h>
// Public API
#include
"dac.h"
#ifdef __cplusplus
extern
"C"
{
#endif
#define DAC1_NODELABEL DT_NODELABEL(dac1)
#define DAC2_NODELABEL DT_NODELABEL(dac2)
#define DAC3_NODELABEL DT_NODELABEL(dac3)
typedef
enum
{
dac_mode_unset
,
dac_mode_constant
,
dac_mode_function
}
dac_mode_t
;
struct
stm32_dac_driver_data
{
DAC_TypeDef
*
dac_struct
;
dac_mode_t
dac_mode
;
};
static
int
dac_stm32_init
(
const
struct
device
*
dev
);
static
void
dac_stm32_set_const_value
(
const
struct
device
*
dev
,
uint8_t
channel
,
uint32_t
value
);
static
void
dac_stm32_set_function
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_function_config_t
*
function_config
);
static
void
dac_stm32_pin_configure
(
const
struct
device
*
dev
,
uint8_t
channel
,
const
dac_pin_config_t
*
pin_config
);
static
void
dac_stm32_start
(
const
struct
device
*
dev
,
uint8_t
channel
);
static
void
dac_stm32_stop
(
const
struct
device
*
dev
,
uint8_t
channel
);
#ifdef __cplusplus
}
#endif
#endif // STM32_DAC_DRIVER_H_
zephyr/nucleo_g474re.overlay
View file @
2615d168
...
...
@@ -84,3 +84,19 @@
&dmamux1 {
status = "okay";
};
/*******/
/* DAC */
/*******/
&dac1 {
status = "okay";
};
&dac2 {
status = "okay";
};
&dac3 {
status = "okay";
};
zephyr/prj.conf
View file @
2615d168
...
...
@@ -45,3 +45,4 @@ CONFIG_ASSERT=y
#CONFIG_OWNTECH_NGND_DRIVER=n
#CONFIG_OWNTECH_DATA_ACQUISITION=n
#CONFIG_OWNTECH_VREFBUF_DRIVER=n
#CONFIG_OWNTECH_DAC_DRIVER=n
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment