ADC1 sur Zest_Adapter_Shield : error code (-134)

Bonjour,

j’essaie de faire fonctionner l’ADC1 channel 3, qui est cablé à l’entrée A0 du shield Arduino via le module Zest_Adapter_Shield. J’ai utilisé le code fourni zephyr/samples/drivers/adc/adc_dt/ que j’ai adapté pour qu’il colle à la carte zest_core_stm32l4a6rg.dts.

Le code compile correctement, mais j’ai une erreur “Could not setup channel #3 (-134)” soulevée par l’appel de la fonction adc_channel_setup_dt().

J’ai bien regardé la doc du stm32l4a6rg et comment le device est déclaré dans le dt de la carte, mais je n’arrive pas à trouver pourquoi l’erreur -134.

Auriez-vous une idée ?

Olivier.

#include <zephyr/kernel.h>

#include <zephyr/device.h>

#include <zephyr/devicetree.h>

#include <zephyr/drivers/adc.h>

#include <zephyr/sys/printk.h>





// On récupère le DEVICE global de l'ADC1 

#if !DT_NODE_EXISTS(DT_NODELABEL(adc1))

#error "Node adc1 not found in devicetree"

#endif


#define ADC_NODE DT_NODELABEL(adc1)




/* 

 * Configuration manuelle de la structure.

  */

static const struct adc_dt_spec adc_channel = {

    .dev = DEVICE_DT_GET(ADC_NODE),

    .channel_id = 3,         /* Canal 3 (zest_Adapter_Shield Arduino A0) */

    .resolution = 12,

    .oversampling = 0,  

    .channel_cfg = {

        .channel_id = 3,

        .gain = ADC_GAIN_1,              

        .reference = ADC_REF_INTERNAL,   

        .acquisition_time = ADC_ACQ_TIME_DEFAULT,

        .differential = 0,

    },

};




int main(void)

{

int err;

uint32_t count = 0;

uint16_t buf;




struct adc_sequence sequence = {

        .buffer = &buf,

        .buffer_size = sizeof(buf),

    };




    /* Vérifie si le device ADC est prêt */

if (!adc_is_ready_dt(&adc_channel)) {

printk("ADC controller device %s not ready\n", adc_channel.dev->name);

return 0;

    }




    /* 

     * Setup du canal :

     * Va maintenant lire .channel_cfg correctement rempli ci-dessus.

     */

    err = adc_channel_setup_dt(&adc_channel);

if (err < 0) {

printk("Could not setup channel (%d)\n", err);

return 0;

    }




printk("ADC lecture sur %s (canal %d)\n", adc_channel.dev->name, adc_channel.channel_id);




while (1) {

        /* Initialise la séquence avec les paramètres (résolution...) */

        err = adc_sequence_init_dt(&adc_channel, &sequence);

if (err < 0) {

printk("Could not initalize sequence (%d)\n", err);

continue;

        }




        /* Lecture */

        err = adc_read(adc_channel.dev, &sequence);

if (err < 0) {

printk("Could not read (%d)\n", err);

continue;

        }




        /* Conversion en millivolts */

int32_t val_mv = buf;

        err = adc_raw_to_millivolts_dt(&adc_channel, &val_mv);

if (err < 0) {

printk("Buffer conversion failed (%d)\n", err);

        } else {

printk("- %u: ADC raw=%d, voltage=%d mV\n", count++, buf, val_mv);

        }




k_sleep(K_MSEC(1000));

    }

return 0;

}


Bonjour,

L’erreur vient de la mauvaise initialisation de la structure adc_dt_spec. Il est préférable de remplir cette structure avec les informations définies dans dans le devicetree à l’aide des macros.

Pour faire cela, ajouter la définition de l’ADC et du channel dans un overlay (app.overlay ou boards/zest_core_stm32l4a6rg.overlay)

/ {
	zephyr,user {
		io-channels = <&adc1 3>;
	};
};

Puis remplacer l’initialisation de l’ADC par :

static const struct adc_dt_spec adc_channel =
    ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 0);

Cela devrait corriger le problème.

Si des modifications de configuration des ADC sont nécessaires, elles devront être faites dans le devicetree.

Clément

1 Like

J’ai finalement trouvé une solution la voici :

  1. L’overlay

contenu du fichier zest_core_stm32l4a6rg.overlay placé à la racine de mon projet

/ {

    zephyr,user {

io-channels = <&adc1 3>; // ADC1 channel 3 (A0)

    };

};

&adc1 {

#address-cells = <1>;

#size-cells = <0>;

channel@3 {

reg = <3>;

zephyr,gain = "ADC_GAIN_1";

zephyr,reference = "ADC_REF_INTERNAL";

zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;

zephyr,resolution = <12>;

    };

status = "okay";

};
  1. Le code consommateur de l’overlay s’appuyant sur l’exemple présent dans les samples
#include <zephyr/kernel.h>

#include <zephyr/device.h>

#include <zephyr/devicetree.h>

#include <zephyr/drivers/adc.h>

#include <zephyr/sys/printk.h>


static const struct adc_dt_spec adc_channel = ADC_DT_SPEC_GET(DT_PATH(zephyr_user));

int main(void)

{

int err;

uint32_t count = 0;

uint16_t buf;


struct adc_sequence sequence = {

        .buffer = &buf,

        .buffer_size = sizeof(buf),

    };




    /* Vérifie si le device ADC est prêt */

if (!adc_is_ready_dt(&adc_channel)) {

printk("ADC controller device %s not ready\n", adc_channel.dev->name);

return 0;

    }

    err = adc_channel_setup_dt(&adc_channel);

if (err < 0) {

printk("Could not setup channel (%d)\n", err);

return 0;

    }

printk("ADC lecture sur %s (canal %d)\n", adc_channel.dev->name, adc_channel.channel_id);

while (1) {

        /* Initialise la séquence avec les paramètres (résolution...) */

        err = adc_sequence_init_dt(&adc_channel, &sequence);

if (err < 0) {

printk("Could not initalize sequence (%d)\n", err);

continue;

        }

        /* Lecture */

        err = adc_read(adc_channel.dev, &sequence);

if (err < 0) {

printk("Could not read (%d)\n", err);

continue;

        }

        /* Conversion en millivolts */

int32_t val_mv = buf;

        err = adc_raw_to_millivolts_dt(&adc_channel, &val_mv);

if (err < 0) {

printk("Buffer conversion failed (%d)\n", err);

        } else {

printk("- %u: ADC raw=%d, voltage=%d mV\n", count++, buf, val_mv);

        }

k_sleep(K_MSEC(1000));

    }

return 0;

}
  1. le prj.conf

CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y
CONFIG_ADC=y
CONFIG_CBPRINTF_FP_SUPPORT=y

Le potentiomètre est branché sur le port A0 du shield Arduino via le zest_Adapter_Shield et c’est bon :+1:

Je ne sais pas pourquoi, l’exemple précédent ne fonctionnait pas cela me paraissait cohérent dans la démarche d’autant que l’ADC1 est bien décrit dans le DT fourni avec la 6tron, et que CMake trouvait la ref sans problème !?

A bientôt,

Olivier.