blob: bb1ca9dbb55bd2f37bfe724f0c7f0afcab9f3ab3 [file] [log] [blame]
/*
* Copyright (c) 2024 STMicroelectronics
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/printk.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/entropy.h>
#include <string.h>
#define SLEEP_TIME_STOP0_MS 800
#define SLEEP_TIME_STOP1_MS 1500
#define SLEEP_TIME_STANDBY_MS 3000
#define SLEEP_TIME_BUSY_MS 2000
static const struct gpio_dt_spec led =
GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif
#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
DT_SPEC_AND_COMMA)
};
const struct device *rng_dev;
#define BUFFER_LENGTH 3
static uint8_t entropy_buffer[BUFFER_LENGTH] = {0};
static int adc_test(void)
{
int err;
static uint32_t count;
uint16_t buf;
struct adc_sequence sequence = {
.buffer = &buf,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(buf),
};
/* Configure channels individually prior to sampling. */
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
if (!adc_is_ready_dt(&adc_channels[i])) {
printk("ADC controller device %s not ready\n", adc_channels[i].dev->name);
return 0;
}
err = adc_channel_setup_dt(&adc_channels[i]);
if (err < 0) {
printk("Could not setup channel #%d (%d)\n", i, err);
return 0;
}
}
printk("ADC reading[%u]:\n", count++);
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
int32_t val_mv;
printk("- %s, channel %d: ",
adc_channels[i].dev->name,
adc_channels[i].channel_id);
(void)adc_sequence_init_dt(&adc_channels[i], &sequence);
err = adc_read_dt(&adc_channels[i], &sequence);
if (err < 0) {
printk("Could not read (%d)\n", err);
continue;
}
/*
* If using differential mode, the 16 bit value
* in the ADC sample buffer should be a signed 2's
* complement value.
*/
if (adc_channels[i].channel_cfg.differential) {
val_mv = (int32_t)((int16_t)buf);
} else {
val_mv = (int32_t)buf;
}
printk("%"PRId32, val_mv);
err = adc_raw_to_millivolts_dt(&adc_channels[i],
&val_mv);
/* conversion to mV may not be supported, skip if not */
if (err < 0) {
printk(" (value in mV not available)\n");
} else {
printk(" = %"PRId32" mV\n", val_mv);
}
}
return 0;
}
void print_buf(uint8_t *buffer)
{
int i;
int count = 0;
for (i = 0; i < BUFFER_LENGTH; i++) {
printk(" 0x%02x", buffer[i]);
if (buffer[i] == 0x00) {
count++;
}
}
printk("\n");
}
int main(void)
{
__ASSERT_NO_MSG(gpio_is_ready_dt(&led));
rng_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_entropy));
if (!device_is_ready(rng_dev)) {
printk("error: random device not ready");
}
printk("Device ready\n");
while (true) {
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
adc_test();
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
gpio_pin_set_dt(&led, 0);
k_msleep(SLEEP_TIME_STOP0_MS);
printk("Exit Stop0\n");
gpio_pin_set_dt(&led, 1);
adc_test();
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
gpio_pin_set_dt(&led, 0);
k_msleep(SLEEP_TIME_STOP1_MS);
printk("Exit Stop1\n");
(void)memset(entropy_buffer, 0x00, BUFFER_LENGTH);
entropy_get_entropy(rng_dev, (char *)entropy_buffer, BUFFER_LENGTH);
printk("Sync entropy: ");
print_buf(entropy_buffer);
gpio_pin_set_dt(&led, 1);
adc_test();
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
gpio_pin_configure_dt(&led, GPIO_DISCONNECTED);
k_msleep(SLEEP_TIME_STANDBY_MS);
printk("Exit Standby\n");
}
return 0;
}