Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
Core
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
OwnTech
Power API
Core
Merge requests
!55
ADC driver:
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
ADC driver:
cfoucher/core:adc_rework
into
main
Overview
0
Commits
8
Pipelines
0
Changes
24
Merged
Clément Foucher
requested to merge
cfoucher/core:adc_rework
into
main
1 year ago
Overview
0
Commits
8
Pipelines
0
Changes
24
Expand
Identify ADCs by their reg addr instead of their label, as this property is going deprecated in Zephyr.
Move all low-level calls to adc_core instead of adc_channels.
Move adc_channels into Data Acquisition.
Add an ADC stop function.
ADC driver module self-manages ADC init.
0
0
Merge request reports
Compare
main
version 1
e562538b
1 year ago
main (base)
and
latest version
latest version
668ef6e5
8 commits,
1 year ago
version 1
e562538b
7 commits,
1 year ago
24 files
+
760
−
753
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
24
Search (e.g. *.vue) (Ctrl+P)
zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c
+
131
−
82
Options
/*
* Copyright (c) 2021-202
2
LAAS-CNRS
* Copyright (c) 2021-202
3
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
@@ -18,7 +18,7 @@
*/
/**
* @date 202
2
* @date 202
3
*
* @author Clément Foucher <clement.foucher@laas.fr>
*/
@@ -28,7 +28,6 @@
#include
<stm32_ll_adc.h>
// Current module private functions
#include
"../src/adc_channels.h"
#include
"../src/adc_core.h"
// Current file header
@@ -39,153 +38,203 @@
// Constants
#define NUMBER_OF_ADCS 4
#define NUMBER_OF_CHANNELS_PER_ADC 16
/////
// Local variables
static
uint32_t
adc_trigger_sources
[
NUMBER_OF_ADCS
]
=
{
0
};
static
uint32_t
adc_discontinuous_mode
[
NUMBER_OF_ADCS
]
=
{
0
};
static
adc_ev_src_t
adc_trigger_sources
[
NUMBER_OF_ADCS
]
=
{
software
};
static
uint32_t
adc_discontinuous_mode
[
NUMBER_OF_ADCS
]
=
{
0
};
static
uint32_t
enabled_channels_count
[
NUMBER_OF_ADCS
]
=
{
0
};
static
bool
enable_dma
[
NUMBER_OF_ADCS
]
=
{
false
};
static
uint32_t
enabled_channels
[
NUMBER_OF_ADCS
][
NUMBER_OF_CHANNELS_PER_ADC
]
=
{
0
};
/////
// Public API
void
adc_
init
(
)
void
adc_
configure_trigger_source
(
uint8_t
adc_number
,
adc_ev_src_t
trigger_source
)
{
adc_core_init
();
adc_channels_init
();
if
(
(
adc_number
==
0
)
||
(
adc_number
>
NUMBER_OF_ADCS
)
)
return
;
adc_trigger_sources
[
adc_number
-
1
]
=
trigger_source
;
}
void
adc_
set_dual_mode
(
uint8_t
dual_mode
)
void
adc_
configure_discontinuous_mode
(
uint8_t
adc_number
,
uint32_t
discontinuous_count
)
{
adc_core_set_dual_mode
(
dual_mode
);
if
(
(
adc_number
==
0
)
||
(
adc_number
>
NUMBER_OF_ADCS
)
)
return
;
adc_discontinuous_mode
[
adc_number
-
1
]
=
discontinuous_count
;
}
void
adc_
configure_trigger_source
(
uint8_t
adc_number
,
adc_ev_src_t
trigger_source
)
void
adc_
add_channel
(
uint8_t
adc_number
,
uint8_t
channel
)
{
/////
// Convert to LL constants
if
(
(
adc_number
==
0
)
||
(
adc_number
>
NUMBER_OF_ADCS
)
)
return
;
uint32_t
trig
;
switch
(
trigger_source
)
{
case
hrtim_ev1
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG1
;
break
;
case
hrtim_ev2
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG2
;
break
;
case
hrtim_ev3
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG3
;
break
;
case
hrtim_ev4
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG4
;
break
;
case
software
:
default:
trig
=
LL_ADC_REG_TRIG_SOFTWARE
;
break
;
}
uint8_t
adc_index
=
adc_number
-
1
;
// Only store configuration: it must be applied after ADC enable
if
(
(
adc_number
>
0
)
&&
(
adc_number
<=
NUMBER_OF_ADCS
)
)
{
adc_trigger_sources
[
adc_number
-
1
]
=
trig
;
}
if
(
enabled_channels_count
[
adc_index
]
==
NUMBER_OF_CHANNELS_PER_ADC
)
return
;
enabled_channels
[
adc_index
][
enabled_channels_count
[
adc_index
]]
=
channel
;
enabled_channels_count
[
adc_index
]
++
;
}
void
adc_
configure_discontinuous_mode
(
uint8_t
adc_number
,
uint
32
_t
dicontinuous_count
)
void
adc_
remove_channel
(
uint8_t
adc_number
,
uint
8
_t
channel
)
{
// Only store configuration: it must be applied after ADC enable
if
(
(
adc_number
>
0
)
&&
(
adc_number
<=
NUMBER_OF_ADCS
)
)
if
(
(
adc_number
==
0
)
||
(
adc_number
>
NUMBER_OF_ADCS
)
)
return
;
uint8_t
adc_index
=
adc_number
-
1
;
for
(
int
i
=
0
;
i
<
NUMBER_OF_CHANNELS_PER_ADC
;
i
++
)
{
adc_discontinuous_mode
[
adc_number
-
1
]
=
dicontinuous_count
;
if
(
enabled_channels
[
adc_index
][
i
]
==
channel
)
{
for
(
int
j
=
i
;
j
<
NUMBER_OF_CHANNELS_PER_ADC
-
1
;
j
++
)
{
enabled_channels
[
adc_index
][
i
]
=
enabled_channels
[
adc_index
][
i
+
1
];
}
enabled_channels
[
adc_index
][
NUMBER_OF_CHANNELS_PER_ADC
-
1
]
=
0
;
enabled_channels_count
[
adc_index
]
--
;
break
;
}
}
}
int8_t
adc_configure_
adc_channels
(
uint8_t
adc_number
,
const
char
*
channel_list
[],
uint8_t
channel_count
)
void
adc_configure_
use_dma
(
uint8_t
adc_number
,
bool
use_dma
)
{
return
adc_channnels_configure_adc_channels
(
adc_number
,
channel_list
,
channel_count
);
if
(
(
adc_number
==
0
)
||
(
adc_number
>
NUMBER_OF_ADCS
)
)
return
;
enable_dma
[
adc_number
-
1
]
=
use_dma
;
}
void
adc_start
()
{
uint8_t
enabled_channels_count
[
NUMBER_OF_ADCS
];
/////
// Initialize ADCs
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
{
enabled_channels_count
[
i
]
=
adc_channels_get_enabled_channels_count
(
i
+
1
);
}
adc_core_init
();
/////
// Pre-enable configuration
// Nothing here for now.
// If some channels have to be set as differential,
// or ADCs have to be set as dual mode,
// this shoud be done here.
/////
// Enable ADCs
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
for
(
int
i
=
1
;
i
<=
NUMBER_OF_ADCS
;
i
++
)
{
if
(
enabled_channels_count
[
i
]
>
0
)
{
adc_core_enable
(
i
+
1
);
}
adc_core_enable
(
i
);
}
/////
// Configure ADCs channels
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
// Post-enable configuration
for
(
uint8_t
adc_num
=
1
;
adc_num
<=
NUMBER_OF_ADCS
;
adc_num
++
)
{
if
(
enabled_channels_count
[
i
]
>
0
)
uint8_t
adc_index
=
adc_num
-
1
;
if
(
enabled_channels_count
[
adc_index
]
>
0
)
{
adc_channels_configure
(
i
+
1
);
for
(
int
channel_index
=
0
;
channel_index
<
NUMBER_OF_CHANNELS_PER_ADC
;
channel_index
++
)
{
if
(
enabled_channels
[
adc_index
][
channel_index
]
==
0
)
break
;
adc_core_configure_channel
(
adc_num
,
enabled_channels
[
adc_index
][
channel_index
],
channel_index
+
1
);
}
}
}
/////
// Configure ADCs
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
for
(
uint8_t
adc_num
=
1
;
adc_num
<=
NUMBER_OF_ADCS
;
adc_num
++
)
{
if
(
enabled_channels_count
[
i
]
>
0
)
uint8_t
adc_index
=
adc_num
-
1
;
if
(
enabled_channels_count
[
adc_index
]
>
0
)
{
adc_core_configure_dma_mode
(
i
+
1
);
adc_core_configure_dma_mode
(
adc_num
,
enable_dma
[
adc_index
]
);
}
}
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
for
(
uint8_t
adc_num
=
1
;
adc_num
<
=
NUMBER_OF_ADCS
;
adc_num
++
)
{
if
(
(
enabled_channels_count
[
i
]
>
0
)
&&
(
adc_discontinuous_mode
[
i
]
!=
0
)
)
uint8_t
adc_index
=
adc_num
-
1
;
if
(
enabled_channels_count
[
adc_index
]
>
0
)
{
adc_core_configure_discontinuous_mode
(
i
+
1
,
adc_discontinuous_mode
[
i
]);
adc_core_configure_discontinuous_mode
(
adc_num
,
adc_discontinuous_mode
[
adc_index
]);
}
}
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
for
(
uint8_t
adc_num
=
1
;
adc_num
<
=
NUMBER_OF_ADCS
;
adc_num
++
)
{
if
(
(
enabled_channels_count
[
i
]
>
0
)
&&
(
adc_trigger_sources
[
i
]
!=
0
)
)
uint8_t
adc_index
=
adc_num
-
1
;
if
(
enabled_channels_count
[
adc_index
]
>
0
)
{
adc_core_configure_trigger_source
(
i
+
1
,
LL_ADC_REG_TRIG_EXT_RISING
,
adc_trigger_sources
[
i
]);
// Convert to LL constants
uint32_t
trig
;
switch
(
adc_trigger_sources
[
adc_index
])
{
case
hrtim_ev1
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG1
;
break
;
case
hrtim_ev2
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG2
;
break
;
case
hrtim_ev3
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG3
;
break
;
case
hrtim_ev4
:
trig
=
LL_ADC_REG_TRIG_EXT_HRTIM_TRG4
;
break
;
case
software
:
default:
trig
=
LL_ADC_REG_TRIG_SOFTWARE
;
break
;
}
adc_core_configure_trigger_source
(
adc_num
,
LL_ADC_REG_TRIG_EXT_RISING
,
trig
);
}
}
/////
// Finally, start ADCs
for
(
uint8_t
i
=
0
;
i
<
NUMBER_OF_ADCS
;
i
++
)
// Start ADCs
for
(
uint8_t
adc_num
=
1
;
adc_num
<=
NUMBER_OF_ADCS
;
adc_num
++
)
{
if
(
enabled_channels_count
[
i
]
>
0
)
uint8_t
adc_index
=
adc_num
-
1
;
if
(
enabled_channels_count
[
adc_index
]
>
0
)
{
adc_core_start
(
i
+
1
);
adc_core_start
(
adc_num
,
enabled_channels_count
[
adc_index
]
);
}
}
}
const
char
*
adc_get_channel_name
(
uint8_t
adc_number
,
uint8_t
channel_rank
)
void
adc_stop
(
)
{
return
adc_channels_get_channel_name
(
adc_number
,
channel_rank
);
for
(
uint8_t
adc_num
=
1
;
adc_num
<=
NUMBER_OF_ADCS
;
adc_num
++
)
{
uint8_t
adc_index
=
adc_num
-
1
;
if
(
enabled_channels_count
[
adc_index
]
>
0
)
{
adc_core_stop
(
adc_num
);
}
}
}
uint8_t
adc_get_enabled_channels_count
(
uint8_t
adc_num
)
void
adc_trigger_software_conversion
(
uint8_t
adc_num
ber
)
{
return
adc_channels_get_enabled_channels_coun
t
(
adc_num
);
adc_core_star
t
(
adc_num
ber
,
1
);
}
void
adc_software_trigger_conversion
(
uint8_t
adc_number
)
{
adc_core_start
(
adc_number
);
}
\ No newline at end of file
Loading