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