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
eff00d2d
Commit
eff00d2d
authored
Jun 04, 2021
by
Clément Foucher
Browse files
Added OwnTech's Zephyr modules to the tree.
parent
fa005f4d
Changes
43
Hide whitespace changes
Inline
Side-by-side
zephyr/CMakeLists.txt
View file @
eff00d2d
# Macro to list all subdirectories in a specified directory
MACRO
(
SUBDIRLIST result curdir
)
FILE
(
GLOB children RELATIVE
${
curdir
}
${
curdir
}
/*
)
SET
(
dirlist
""
)
FOREACH
(
child
${
children
}
)
IF
(
IS_DIRECTORY
${
curdir
}
/
${
child
}
)
LIST
(
APPEND dirlist
${
curdir
}
/
${
child
}
)
ENDIF
()
ENDFOREACH
()
SET
(
${
result
}
${
dirlist
}
)
ENDMACRO
()
# Define SUBDIRS as the list of all subdirectories of the modules directory
SUBDIRLIST
(
SUBDIRS
${
CMAKE_CURRENT_SOURCE_DIR
}
/modules
)
# Append found modules to zephyr extra modules variable
list
(
APPEND ZEPHYR_EXTRA_MODULES
${
SUBDIRS
}
)
# Configure Zephyr
cmake_minimum_required
(
VERSION 3.13.1
)
find_package
(
Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}
)
...
...
zephyr/modules/owntech_data_acquisition/zephyr/CMakeLists.txt
0 → 100644
View file @
eff00d2d
if
(
CONFIG_OWNTECH_DATA_ACQUISITION
)
zephyr_include_directories
(
.
)
zephyr_library
()
zephyr_library_sources
(
./adc/adc.c
./adc/adc_channels.c
./adc/adc_core.c
./adc/adc_helper.c
./dma/dma.c
./data_dispatch/data_dispatch.c
./data_acquisition.c
)
endif
()
zephyr/modules/owntech_data_acquisition/zephyr/Kconfig
0 → 100644
View file @
eff00d2d
config OWNTECH_DATA_ACQUISITION
bool "Enable OwnTech data acquisition using ADCs"
default y
select DMA
zephyr/modules/owntech_data_acquisition/zephyr/adc/adc.c
0 → 100644
View file @
eff00d2d
/*
* 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>
*/
// STM32 LL
#include
<stm32g4xx_ll_adc.h>
// OwnTech API
#include
"adc_channels.h"
#include
"adc_core.h"
/////
// Private functions
/**
* ADC 1 OwnTech's specific configuration.
*/
static
void
_adc_configure_adc_1
()
{
// Set regular sequence length
LL_ADC_REG_SetSequencerLength
(
ADC1
,
adc_channels_get_channels_count
(
1
)
-
1
);
// TO TEST
// Set discontinuous mode: first event triggers first channel conversion,
// next event will convert the next channel in the sequence, and so on
// until all channels are converted, then restart from fisrt channel.
// RM: 21.4.20
//LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_1RANK);
// Enable dma and circular mode
LL_ADC_REG_SetDMATransfer
(
ADC1
,
LL_ADC_REG_DMA_TRANSFER_UNLIMITED
);
/////
// Set trigger source: only for ADC 1 as we operate in dual mode
// (ADC 2 triggered by ADC 1)
// Enable external trigger on hrtim_adc_trg1
LL_ADC_REG_SetTriggerEdge
(
ADC1
,
LL_ADC_REG_TRIG_EXT_RISING
);
// RM Table 163. adc_ext_trg21 hrtim_adc_trg1 EXTSEL = 0x10101
LL_ADC_REG_SetTriggerSource
(
ADC1
,
LL_ADC_REG_TRIG_EXT_HRTIM_TRG1
);
}
/**
* ADC 2 OwnTech's specific configuration.
*/
static
void
_adc_configure_adc_2
()
{
// Set regular sequence length
LL_ADC_REG_SetSequencerLength
(
ADC2
,
adc_channels_get_channels_count
(
2
)
-
1
);
// TO TEST
// Set discontinuous mode: first event triggers first channel conversion,
// next event will convert the next channel in the sequence, and so on
// until all channels are converted, then restart from fisrt channel.
// RM: 21.4.20
//LL_ADC_REG_SetSequencerDiscont(ADC2, LL_ADC_REG_SEQ_DISCONT_1RANK);
// Enable dma and circular mode
LL_ADC_REG_SetDMATransfer
(
ADC2
,
LL_ADC_REG_DMA_TRANSFER_UNLIMITED
);
}
/////
// Public API
/**
* Configure ADC and DMA according to OwnTech
* board requirements.
*/
void
adc_init
()
{
// Initialize ADC
adc_core_init
();
adc_core_set_dual_mode
();
// Initialize channels
adc_channels_init
();
// Enable ADC
adc_core_enable
(
ADC1
);
adc_core_enable
(
ADC2
);
// Perform post-enable ADC configuration
adc_channels_configure
(
ADC1
);
adc_channels_configure
(
ADC2
);
_adc_configure_adc_1
();
_adc_configure_adc_2
();
// Finally, start ADCs
adc_core_start
(
ADC1
);
adc_core_start
(
ADC2
);
}
zephyr/modules/owntech_data_acquisition/zephyr/adc/adc.h
0 → 100644
View file @
eff00d2d
/*
* 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>
* @brief This is the main include for ADC configuration.
*/
#ifndef ADC_H_
#define ADC_H_
#ifdef __cplusplus
extern
"C"
{
#endif
/**
* @brief Initializes ADC1 and ADC2 driver.
*/
void
adc_init
();
#ifdef __cplusplus
}
#endif
#endif // ADC_H_
zephyr/modules/owntech_data_acquisition/zephyr/adc/adc_channels.c
0 → 100644
View file @
eff00d2d
/*
* 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
*/
/**
* @brief ADC driver for stm32g474re
*
* @author Hugues Larrive <hugues.larrive@laas.fr>
* @author Clément Foucher <clement.foucher@laas.fr>
*/
// Stdlib
#include
<stdlib.h>
// Current file header
#include
"adc_channels_private.h"
// OwnTech API
#include
"adc_helper.h"
#include
"adc_core.h"
/////
// Variables
static
channel_prop_t
channels_props
[]
=
{
DT_FOREACH_CHILD
(
ADC_INPUTS_NODELABEL
,
CHANNEL_WRITE_PROP
)
};
static
uint8_t
channels_in_adc1_count
;
static
uint8_t
channels_in_adc2_count
;
static
channel_prop_t
**
adc1_channels_list
;
static
channel_prop_t
**
adc2_channels_list
;
/////
// ADC channels private functions
/**
* Counts device-tree configured channels in each ADC.
*/
static
void
_adc_channels_count
()
{
// Count total number of channels
channels_in_adc1_count
=
0
;
channels_in_adc2_count
=
0
;
for
(
int
i
=
0
;
i
<
CHANNEL_COUNT
;
i
++
)
{
ADC_TypeDef
*
adc
=
_get_adc_by_name
(
channels_props
[
i
].
adc
);
if
(
adc
==
ADC1
)
{
channels_in_adc1_count
++
;
}
else
if
(
adc
==
ADC2
)
{
channels_in_adc2_count
++
;
}
}
// Build a list of channels by ADC
adc1_channels_list
=
malloc
(
sizeof
(
channel_prop_t
*
)
*
channels_in_adc1_count
);
adc2_channels_list
=
malloc
(
sizeof
(
channel_prop_t
*
)
*
channels_in_adc2_count
);
int
adc1_index
=
0
;
int
adc2_index
=
0
;
for
(
int
i
=
0
;
i
<
CHANNEL_COUNT
;
i
++
)
{
ADC_TypeDef
*
adc
=
_get_adc_by_name
(
channels_props
[
i
].
adc
);
if
(
adc
==
ADC1
)
{
adc1_channels_list
[
adc1_index
]
=
&
channels_props
[
i
];
adc1_index
++
;
}
else
if
(
adc
==
ADC2
)
{
adc2_channels_list
[
adc2_index
]
=
&
channels_props
[
i
];
adc2_index
++
;
}
}
}
/**
* Differential channel setup.
* Must be done before ADC is enabled.
*/
static
void
_adc_channels_differential_setup
()
{
for
(
int
i
=
0
;
i
<
CHANNEL_COUNT
;
i
++
)
{
if
(
channels_props
[
i
].
is_differential
)
{
ADC_TypeDef
*
adc
=
_get_adc_by_name
(
channels_props
[
i
].
adc
);
if
(
adc
!=
NULL
)
{
adc_core_set_channel_differential
(
adc
,
channels_props
[
i
].
number
);
}
}
}
}
/**
* Internal path setup.
* Currently done before ADC is enabled,
* but is is correct? No hint in RM on this.
*/
void
_adc_channels_internal_path_setup
()
{
uint8_t
vts
=
0
;
uint8_t
vbat
=
0
;
uint8_t
vref
=
0
;
for
(
int
i
=
0
;
i
<
CHANNEL_COUNT
;
i
++
)
{
if
(
channels_props
[
i
].
number
==
__LL_ADC_CHANNEL_TO_DECIMAL_NB
(
LL_ADC_CHANNEL_TEMPSENSOR_ADC1
))
vts
=
1
;
if
(
channels_props
[
i
].
number
==
__LL_ADC_CHANNEL_TO_DECIMAL_NB
(
LL_ADC_CHANNEL_VBAT
))
vbat
=
1
;
if
(
channels_props
[
i
].
number
==
__LL_ADC_CHANNEL_TO_DECIMAL_NB
(
LL_ADC_CHANNEL_VREFINT
))
vref
=
1
;
}
adc_core_configure_internal_paths
(
vts
,
vbat
,
vref
);
}
/////
// ADC channls public functions
/**
* Performs internal data structures initialization
* and pre-ADC enable init.
* Must be called before adc_core_enable()
*/
void
adc_channels_init
()
{
_adc_channels_count
();
_adc_channels_differential_setup
();
_adc_channels_internal_path_setup
();
}
/**
* ADC channel configuration.
* Sets sequencer ranks and channels sampling time.
*/
void
adc_channels_configure
(
ADC_TypeDef
*
adc
)
{
uint8_t
channel
;
uint8_t
rank
=
1
;
ADC_TypeDef
*
channel_adc
;
for
(
int
i
=
0
;
i
<
CHANNEL_COUNT
;
i
++
)
{
channel
=
channels_props
[
i
].
number
;
channel_adc
=
_get_adc_by_name
(
channels_props
[
i
].
adc
);
// Regular sequencer
if
(
channel_adc
==
adc
)
{
LL_ADC_REG_SetSequencerRanks
(
adc
,
adc_decimal_nb_to_rank
(
rank
),
__LL_ADC_DECIMAL_NB_TO_CHANNEL
(
channel
)
);
rank
++
;
// Channels sampling time
/* 000: 2.5 ADC clock cycles
* 001: 6.5 ADC clock cycles
* 010: 12.5 ADC clock cycles
* 011: 24.5 ADC clock cycles
* 100: 47.5 ADC clock cycles
* 101: 92.5 ADC clock cycles
* 110: 247.5 ADC clock cycles
* 111: 640.5 ADC clock cycles
*/
/* Vrefint minimum sampling time : 4us
*/
/* Vts minimum sampling time : 5us
*/
/* For 0b110:
* Tadc_clk = 1 / 42.5 MHz = 23.5 ns
* Tsar = 12.5 * Tadc_clk = 293.75 ns
* Tsmpl = 247.5 * Tadc_clk = 5816.25 ns
* Tconv = Tsmpl + Tsar = 6.11 us
* -> Fconv up to 163.6 KSPS for 1 channel per ADC
* Fconv up to 27.2 KSPS with the 6 channels actally
* used on the ADC1
*
* For 0b001 (ok for voltage):
* Tadc_clk = 1 / 42.5 MHz = 23.5 ns
* Tsar = 12.5 * Tadc_clk = 293.75 ns
* Tsmpl = 6.5 * Tadc_clk = 152.75 ns
* Tconv = Tsmpl + Tsar = 446.4 ns
* -> Fconv up to 2239 KSPS for 1 channel per ADC
* Fconv up to 373 KSPS with the 6 channels actally
* used on the ADC1
*
* For 0b101 (ok for current):
* Tadc_clk = 1 / 42.5 MHz = 23.5 ns
* Tsar = 12.5 * Tadc_clk = 293.75 ns
* Tsmpl = 92.5 * Tadc_clk = 2173.75 ns
* Tconv = Tsmpl + Tsar = 2.47 µs
* -> Fconv up to 404 KSPS for 1 channel per ADC
* Fconv up to 134 KSPS for 3 channels actally
* used on each ADC
*/
LL_ADC_SetChannelSamplingTime
(
adc
,
__LL_ADC_DECIMAL_NB_TO_CHANNEL
(
channel
),
LL_ADC_SAMPLINGTIME_92CYCLES_5
);
}
}
}
char
*
adc_channels_get_channel_name
(
uint8_t
adc_num
,
uint8_t
channel_rank
)
{
if
(
adc_num
==
1
)
return
adc1_channels_list
[
channel_rank
]
->
name
;
else
if
(
adc_num
==
2
)
return
adc2_channels_list
[
channel_rank
]
->
name
;
else
return
NULL
;
}
uint8_t
adc_channels_get_channels_count
(
uint8_t
adc_num
)
{
if
(
adc_num
==
1
)
return
channels_in_adc1_count
;
else
if
(
adc_num
==
2
)
return
channels_in_adc2_count
;
else
return
0xFF
;
}
\ No newline at end of file
zephyr/modules/owntech_data_acquisition/zephyr/adc/adc_channels.h
0 → 100644
View file @
eff00d2d
/*
* 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
*/
/**
* @brief This is the public include for adc_channels.h
*
* @author Clément Foucher <clement.foucher@laas.fr>
*/
#ifndef ADC_CHANNELS_H_
#define ADC_CHANNELS_H_
// Zephyr
#include
<zephyr.h>
#ifdef __cplusplus
extern
"C"
{
#endif
void
adc_channels_init
();
void
adc_channels_configure
(
ADC_TypeDef
*
adc
);
char
*
adc_channels_get_channel_name
(
uint8_t
adc_num
,
uint8_t
channel_rank
);
uint8_t
adc_channels_get_channels_count
(
uint8_t
adc_num
);
#ifdef __cplusplus
}
#endif
#endif // ADC_CHANNELS_H_
zephyr/modules/owntech_data_acquisition/zephyr/adc/adc_channels_private.h
0 → 100644
View file @
eff00d2d
/*
* 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>
* @brief This is the private include file for adc_channels.c.
* It should only be included in C files from the current folder.
*/
#ifndef ADC_CHANNELS_PRIVATE_H_
#define ADC_CHANNELS_PRIVATE_H_
// Zephyr
#include
<zephyr.h>
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
{
char
*
name
;
bool
is_differential
;
uint8_t
number
;
char
*
adc
;
}
channel_prop_t
;
#define ADC_INPUTS_NODELABEL DT_NODELABEL(mychannels)
// Channel properties
#define CHANNEL_NAME(node_id) DT_LABEL(node_id)
#define CHANNEL_IS_DIFF(node_id) DT_PROP(node_id, differential)
#define CHANNEL_NUMBER(node_id) DT_PHA_BY_IDX(node_id, io_channels, 0, input)
#define CHANNEL_ADC(node_id) DT_PROP_BY_PHANDLE_IDX(node_id, io_channels, 0, label)
#define CHANNEL_WRITE_PROP(node_id) \
{ \
.name=CHANNEL_NAME(node_id), \
.is_differential=CHANNEL_IS_DIFF(node_id), \
.number=CHANNEL_NUMBER(node_id), \
.adc=CHANNEL_ADC(node_id) \
},
// Channel count
#define CHANNEL_COUNTER(node_id) +1
#define CHANNEL_COUNT DT_FOREACH_CHILD(ADC_INPUTS_NODELABEL, CHANNEL_COUNTER)
#ifdef __cplusplus
}
#endif
#endif // ADC_CHANNELS_PRIVATE_H_
zephyr/modules/owntech_data_acquisition/zephyr/adc/adc_core.c
0 → 100644
View file @
eff00d2d
/*
* 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
*/
/**