08.05.2018 Views

Elektor Electronics 2018 03 04

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

. . .<br />

Figure 6. Ici, il manque un module...<br />

Si l’on essaie de compiler notre programme dans son état<br />

précédent, on obtient le message d’erreur de la figure 6<br />

parce que les composants téléchargés « normalement » ne<br />

contiennent pas, au moment de la publication de cet article,<br />

les modules nécessaires.<br />

Accédez au portail sous [9] et téléchargez le fichier correspondant<br />

à votre configuration. Extrayez l’archive vers /esp et ajoutez-la<br />

au chemin :<br />

tamhan@TAMHAN14:~/esp$ ls<br />

esp32ulp-elf-binutils esp-idf hello_world<br />

xtensa-esp32-elf<br />

tamhan@TAMHAN14:~/esp$ export PATH="$PATH:$HOME/esp/<br />

esp32ulp-elf-binutils/bin"<br />

Retournez ensuite à make menuconfig et activez l’option<br />

Component Config-Y ESP32-Specific Enable Ultra Low Power<br />

(ULP) Coprocessor. Make menuconfig insère alors (512) RTC<br />

slow memory reserved for coprocessor. Cette allocation de<br />

mémoire sera conservée.<br />

Figure 7. Liste des broches accessibles par l’ULP. (Source : Espressif [7])<br />

La mise en sommeil s’effectue en deux étapes. D’abord, nous<br />

ordonnons à la logique de gestion de l’alimentation de prendre<br />

en compte les commandes de réveil émanant de l’ULP, ensuite,<br />

nous démarrons le programme ULP et mettons le processeur<br />

principal au lit :<br />

}<br />

//Good night<br />

ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );<br />

ESP_ERROR_CHECK( ulp_run((&ulp_entry - RTC_SLOW_<br />

MEM) / sizeof(uint32_t)));<br />

esp_deep_sleep_start();<br />

L’initialisation du programme ULP s’effectue aussi en plusieurs<br />

étapes. On commence par inclure deux constantes produites<br />

par makefile. Ensuite on appelle ulp_load_binary pour charger<br />

les ressources :<br />

extern const uint8_t ulp_main_bin_start[]<br />

asm("_binary_ulp_main_bin_start");<br />

extern const uint8_t ulp_main_bin_end[]<br />

asm("_binary_ulp_main_bin_end");<br />

void init_ulp_program()<br />

{<br />

esp_err_t err = ulp_load_binary(0, ulp_main_bin_<br />

start, (ulp_main_bin_end - ulp_main_bin_start) /<br />

sizeof(uint32_t));<br />

ESP_ERROR_CHECK(err);<br />

Marche – Arrêt !<br />

Si l’on exécute le programme dans l’état précédent, on constate<br />

que le compteur est incrémenté de 3. Cela provient du fait que<br />

le délai court dès l’appel de ulp_run et qu’il faut du temps pour<br />

mettre le processeur principal en sommeil. Les commandes de<br />

réveil arrivant trop tôt sont ignorées et l’ULP s’enferme dans<br />

une espèce de boucle infinie, le temps de trois incrémentations.<br />

Pour régler ce problème, il sufft, lorsqu’on constate le nonendormissement,<br />

de sauter vers le haut dans une boucle de<br />

veille « active » :<br />

exit:<br />

/* Check if the SoC has said INRI already */<br />

READ_RTC_REG(RTC_CNTL_DIAG0_REG, 19, 1)<br />

and r0, r0, 1<br />

jump exit, eq<br />

wake<br />

WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_<br />

ULP_CP_SLP_TIMER_EN, 0)<br />

halt<br />

Pour l’auteur, le désir de mesurer le temps de mise en sommeil<br />

de la MCU était irrésistible. Quelques broches GPIO de l’ESP32<br />

sont des hybrides, qui peuvent être commandées aussi bien<br />

par le module RTC que par le processeur principal ; le tableau<br />

en figure 7 donne la correspondance.<br />

L’initialisation de ces broches s’effectue par une interface de<br />

programmation spéciale, qui se distingue par le préfixe RTC.<br />

Notez que les broches GPIO spécifiées ici (du côté ESP32) le<br />

sont par leur désignation ESP32 :<br />

void init_ulp_program() { . . .<br />

ulp_acti_count=0;<br />

rtc_gpio_init(cpu_num);<br />

36 mars/avril <strong>2018</strong> www.elektormagazine.fr

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!