Déballage du CH32V003, le microcontrôleur à 0.1$

Après avoir commandé un kit de développement CH32V003 sur Tindie, voici qu’il m’arrive par courrier (avec taxes douanière) ce matin dans ma boite aux lettres.

Les deux carte de développement

D’après ce que j’ai compris, il est nécessaire d’avoir la sonde de debug en plus pour pouvoir la programmer. Il va donc falloir que j’attende le deuxième colis pour pouvoir réellement jouer avec.

Ça ne nous empêche pas de la brancher.

Le kit semble fonctionner, les LED s’allument. Cependant nous n’avons rien sur la console Linux, ce qui n’est pas étonnant vu que les deux résistance de shunt de l’USB ne sont pas soudées 😉

Prise en main

WCH propose un logiciel chinois nommée MounRiver pour développer sur son composant. Le logiciel semble accessible en téléchargement au format d’archive xz. On le décompresse avec tar -Jxvf puis on installe les dépendances (Mint) suivante:

$ sudo apt install libgtk-3-0 libgtk-3-dev
$ rulo apt-get install ia32-libs-gtk
$  sudo apt install libatk-wrapper-java libatk-wrapper-java-jni 
Langage du code : JavaScript (javascript)

Pour le lancer il suffit d’executer le «script d’installation» une première fois puis de lancer le binaire :

$ tar -Jxvf /home/fabien/projets/ch32v003/downloads/MounRiver_Studio_Community_Linux_x86_V130.tar.xz
$ cd MounRiver_Studio_Community_Linux_x86_V130/beforeinstall
$ ./start.sh 

Copy Libs
[sudo] Mot de passe de user :        
Register new Libs
copy rules
Reload rules
DONE
$ cd ../MRS_Community/
$ ./MounRiver\ Studio_Community 
Langage du code : JavaScript (javascript)
Saisie d’écran de l’éclipse chinois «mounriver»

Téléchargement du firmware

Pour le moment j’en suis à tenter de télécharger le firmware d’exemple (GPIO_Toggle) dans le micro.

Board chip Status error!

Toolchain «standalone»

La toolchain quand à elle est proposée en téléchargement sur le site du même éditeur.

Pour l’utiliser il suffit de télécharger l’archive MRS_Toolchain_Linux_x64_V1.60.tar.xz et de la décompresser :

$ tar -Jxvf MRS_Toolchain_Linux_x64_V1.60.tar.xz 

Un README explique la marche à suivre pour l’installer.

Les tentatives d’accès au micro avec openocd ne sont pas beaucoup plus fructueuses :

$ cd MRS_Toolchain_Linux_x64_V1.60/OpenOCD/bin
$ ./openocd -f wch-riscv.cfg
Open On-Chip Debugger 0.11.0+dev-02215-gcc0ecfb6d-dirty (2022-10-10-10:35)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Ready for Remote Connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : WCH-LinkE-CH32V307  mod:RV version 2.7 
Error:  WCH-Link failed to connect with riscvchip
Error:  1.Make sure the two-line debug interface has been opened. If not, set board to boot mode then use ISP tool to open it
Error:  2.Please check your physical link connection

Langage du code : JavaScript (javascript)

Ressources

Publié dans Non classé | Marqué avec , | 7 commentaires

Trouvé sur : https://iximiuz.com/en/posts/ssh-tunnels/

Pense bête tunnel ssh

Publié le par admin | Laisser un commentaire

Ma config neovim

Cher blog, je suis en train de migrer vers neovim. Voici donc une prise de notes pour la config.

fichier de config

Ça n’est plus .vimrc, maintenant c’est bien rangé dans ~/.config/nvim/init.vim Le miens est constitué ainsi pour le moment :

" me
let g:Author = "Jean-Paul Martoni"
let g:EmailAuthor = "Moi je dit qu'il @ bluff"

" pour avoir le mulot
set mouse=a

"enregistrer sans help
map <F1> :wall<CR>
imap <F1> <ESC>:wall<CR>i

map <F1> :wall<CR>

set textwidth=80

filetype plugin on
" Alternative: use the following to also enable language-dependent indenting.
" filetype plugin indent on

lua require('plugins')

" better tab completion :
set wildmode=longest,list

" my standard tab config
set tabstop=4
set shiftwidth=4
set expandtab

Langage du code : HTML, XML (xml)

Sensibilité à la casse de la recherche

Par défault neovim est sensible à la casse, ce qui n’était pas le cas de mon ancien vim. Par contre si on place une majuscule dans le mot recherché, vim devenait sensible à la casse. C’est le «smartcase». Pour obtenir se comportement il suffit d’ajouter cette ligne à son init.vim :

" case search
set ignorecase smartcase

Copier coller clique milieu

Pour faire fonctionner le copier/coller clique milieu depuis un autre programme il faut ajouter la ligne suivante à son fichier de config :

set clipboard+=unnamedplusLangage du code : JavaScript (javascript)

Par contre pour le moment ça ne fonctionne pas dans l’autre sens (neovim -> autre programme)

Paramètres d’indentations spécifique à un langage

Pour définir mes propres paramètres pour chaque langages j’utilise ftplugin que j’active dans init.vim :

filetype plugin on

Puis j’ajoute mes config dans le fichier de configuration portant le nom du langage. Par exemple, pour avoir des «TAB» transmuté en deux espaces en C++, j’ajoute les lignes suivantes dans le fichier ~./config/nvim/ftplugin/cpp.vim :

set tabstop=2
set shiftwidth=2
set expandtabLangage du code : JavaScript (javascript)

Folding

Pour replier du texte, la doc est par là. Je me suis fait quelques raccourcis dans ~/.config/nvim/init.vim

"folding
map f zfap

Correction orthographique

La config de Vincent-Roger fonctionne parfaitement chez moi.

"~/.config/nvim/init.vim
" spell languages
set spelllang=fr
nnoremap <silent> <C-s> :set spell!<cr>
inoremap <silent> <C-s> <C-O>:set spell!<cr>Langage du code : HTML, XML (xml)

Mapping des chiffres ronds

Les chiffres entourés d’un disque plein en unicode permettent de marquer des références dans un code quand on fait de la doc. C’est bien pratique d’y avoir accès avec le clavier plutôt que de faire des copier/coller incessant.

" mapping des chiffres ronds
imap œ0 ⓿
imap œ1 ➊
imap œ2 ➋
imap œ3 ➌
imap œ4 ➍
imap œ5 ➎
imap œ6 ➏
imap œ7 ➐
imap œ8 ➑
imap œ9 ➒
imap œ10 ➓

Problèmes

Les problèmes que j’ai encore à résoudre sont :

  • Je n’ai pas l’historique du shell quand je relance une commande avec «:!»

Publié dans Non classé | Marqué avec , | Laisser un commentaire

Ma vieille contour HD 1080p

Petite page de prise de notes sur la caméra contour HD 1080p qui n’est plus commercialisée.

C’est la caméra qui m’a servie à faire quelques vidéos en parapente dont celle-ci.

Je l’ai ressorti de mes cartons car je voudrais m’en servir de «dashcam» à vélo.

Linux

Si on branche l’usb avec une carte sd enfichée dans son lecteur on obtient la trace suivant (notez le magnifique numéro de série !)

 master+* 22h35m13s ± sudo dmesg
[40678.767336] usb 3-2: new high-speed USB device number 7 using xhci_hcd
[40678.918703] usb 3-2: New USB device found, idVendor=115b, idProduct=a271, bcdDevice= 0.00
[40678.918714] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[40678.918718] usb 3-2: Product: Mass Storage
[40678.918721] usb 3-2: Manufacturer: ContourHD
[40678.918723] usb 3-2: SerialNumber: 0123456789
[40678.919202] usb-storage 3-2:1.0: USB Mass Storage device detected
[40678.919625] scsi host2: usb-storage 3-2:1.0
[40679.941353] scsi 2:0:0:0: Direct-Access              ContourHD 1080        PQ: 0 ANSI: 0
[40679.941868] sd 2:0:0:0: Attached scsi generic sg0 type 0
[40679.945665] sd 2:0:0:0: [sda] 61067264 512-byte logical blocks: (31.3 GB/29.1 GiB)
[40679.946712] sd 2:0:0:0: [sda] Write Protect is off
[40679.946717] sd 2:0:0:0: [sda] Mode Sense: 87 00 00 08
[40679.947828] sd 2:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[40679.957863]  sda: sda1
[40679.963572] sd 2:0:0:0: [sda] Attached SCSI removable disk
Langage du code : PHP (php)

La caméra est vue comme un «mass storage» qui est parfaitement lisible sous Linux.

L’insertion d’une carte SD vierge provoque son formatage par la caméra avec la création des fichiers et répertoires suivant :

 $ tree
.
├── DCIM
│   └── 100MEDIA
│       └── FILE0001.MOV
├── FW_RTC.txt
└── MISC

Et le fichier de configuration créé contient les informations suivantes :

FW version:1080 v1.17

SW HI:	A
SW LO:	B
BR:	M
EV:	-1
SHRP:	3
AE:	C
CTST:	56
MIC:	33
Zone:	+02
RTC:	2008/01/01 00:16:36

Format:
SW HI	A:1920x1080 30fps
	B:1280x960 30fps
	C:1280x720 60fps
	D:1280x720 30fps

SW LO	A:1280x720 60fps
	B:1280x960 30fps
	C:1280x720 30fps
	D:848x480 60fps

BR	M:Max
	H:High
	D:Default

EV	-4~4

SHRP	1~5

AE	C:Center
	A:Average
	S:Spot

CTST	1~255

MIC	0~59dB

Zone	-12~+13

RTC	YYYY/MM/DD hh:mm:ss
	YYYY : 2008 - 2099
	MM : 01 - 12
	DD : 01 - 31Langage du code : PHP (php)

On doit pouvoir ce servir de ce fichier pour configurer la caméra je pense. Notamment pour la remettre à la bonne date/heure. Ce qui est important pour faire une dashcam.

FW_RTC.txt

Une discussion sur un forum sur la modification de la configuration avec le fichier.

Publié dans Non classé | Marqué avec , | Laisser un commentaire

Découverte de déchets nucléaires vieux de 2 milliards d’années

Un des reproche qui est souvent fait à l’enfouissement des déchets nucléaires est qu’on ne sera plus là pour les gérer. On les laisse à nos arrière-arrière-etc petits enfants.

Leur dangerosité subsistera pendant des centaines de milliers d’années et les générations futurs ne seront pas capable de gérer un tel fardeau. Et puis, a-t-on le droit de leurs laisser un tel fardeau, personne ne nous a laissé de déchets nucléaires nous !

Personnes certes.

Mais des déchets nucléaires vieux de plusieurs milliards d’années ont déjà été découvert sur terre ! Et on parle bien ici de déchets nucléaires issue de la fission de l’uranium dans des réacteurs nucléaire. Le fameux plutonium et autres transuraniens qui n’existent pas (tout à fait) à l’état naturel.

C’est en 1972 que le physicien Francis Perrin découvre que la mine d’uranium d’Oklo au Gabon renferme des restes de réacteurs nucléaires ayant fonctionné il y a environ 2 milliards d’années.

Et vous savez quoi ? Et bien il n’y a pas eu de grave contamination mondiale à la découverte. Notre civilisation décadente n’a pas été exterminée par la mise au jours de tout ce plutonium.

Non seulement nous avons su les gérer, mais en plus nous avons pu constater que les «déchets» nucléaire ne migrent pas tellement même quand ils sont pris dans le flux d’eau d’une rivière souterraine.

Bref, la dangerosité des déchets nucléaires pour notre civilisation et pour les prochaines restent nettement moins préoccupantes que les énergies fossiles. Énergies qui n’attendent pas des milliers d’années pour détruire notre climat et remettre en cause notre mode de vie.

Publié dans Non classé | Marqué avec , , , , , | Laisser un commentaire

Retour de String en Rust

Alors voila, je veux écrire une fonction qui appelle une commande shell et retourne la chaîne de caractères.

Avec la cagette standard std::process::Command c’est plutôt simple il suffit de faire ça :

use std::process::Command;
//..
    let _cmdret = Command::new("cd-discid")
                            .output()
                            .expect("La commande cd-discid a échouée");
  
//..Langage du code : PHP (php)

L’affichage de _cmdret avec un println! qui va bien me donne la forme de la structure retournée :

println!("{:?}", &_cmdret);
//:Sortie ->
Output { status: ExitStatus(unix_wait_status(0)), stdout: "30027f05 5 150 2422 15072 29219 44022 641\n", stderr: "" }
Langage du code : JavaScript (javascript)

Pour le moment c’est assez simple, si je veux récupérer la chaîne de caractères, il me suffit de prendre le champs stdout :

println!("{:?}", &_cmdret.stdout);
//...
[51, 48, 48, 50, 55, 102, 48, 53, 32, 53, 32, 49, 53, 48, 32, 50, 52, 50, 50, 32, 49, 53, 48, 55, 50, 32, 50, 57, 50, 49, 57, 32, 52, 52, 48, 50, 50, 32, 54, 52, 49, 10]Langage du code : JavaScript (javascript)

Rhaa, mais pourquoi ça s’est transformé en vecteur de u8 ?!

Allons bon, convertissons avec std::str :

use std::str
///
    println!("{:?}", str::from_utf8(&_cmdret.stdout));
///sortie ->
Ok("30027f05 5 150 2422 15072 29219 44022 641\n")
Langage du code : JavaScript (javascript)

On obtient donc une sortie de type Result non ? Notre fonction doit pouvoir s’écrire comme ça alors :

/// Lit le numéro unique du CD se trouvant dans le lecteur
pub fn get_discid() -> Result<String, Box<dyn Error>> {
    let _cmdret = Command::new("cd-discid")
                            .output()
                            .expect("La commande cd-discid a échouée");

    str::from_utf8(&_cmdret.stdout)
}Langage du code : JavaScript (javascript)

Sauf que non, ce que je croyais être un enum «Result» c’est transformé en une chaîne de caractères &str :

22 |     str::from_utf8(&_cmdret.stdout)
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found `&str`
Langage du code : PHP (php)

Rajoutons un Ok() pour lui faire plaisir alors :

22 |     Ok(str::from_utf8(&_cmdret.stdout))
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found enum `Result`
Langage du code : PHP (php)

Et c’est là que je commence à perdre pied, bin oui t’as trouvé un enum Result, puisque c’est ça que j’attends en retour patate !

En browsant désespérément le web j’ai cru trouver qu’il fallait faire un match sur l’enum pour retourner un nouvel enum (mais j’ai pas compris pourquoi le premier ne convenait pas):

/// Lit le numéro unique du CD se trouvant dans le lecteur
pub fn get_discid() -> Result<String, Box<dyn Error>> {
    let _cmdret = Command::new("cd-discid")
                            .output()
                            .expect("La commande cd-discid a échouée");

    match str::from_utf8(&_cmdret.stdout) {
        Ok(v) => Ok(v.to_string()),
        Err(e) => Err(e.into())
    }
}Langage du code : JavaScript (javascript)

À noter qu’il est possible de remplacer le to_string() en into() dans le Ok() mais pas pour le Err().

Bon maintenant ça marche. Mais il me reste un goût amer de celui qui n’a pas compris ce qu’il a écrit. Et j’ai la désagréable impression d’avoir tartiné du code pour pas grand chose !

On doit pouvoir faire plus simple non ?

Bref, la route est encore longue, et c’est pas ce soir que je verrais mes recettes d’histoires terminées 😉

Publié dans Non classé | Marqué avec , , , | 2 commentaires

Prise en main du kit développement XT-ZB1 (BL702)

Synoptique du BL702

Le kit de développement XT-ZB1 DevKit est muni d’un module XT-ZB1 qui intègre un BL702 pour faire du Zigbee et du BLE (BlueTooth Low Energy).

Pinout du kit XT-ZB1

Le SDK est publié sur github et permet de développer sur toutes les cartes de la gamme.

Avec son convertisseur USB-UART et l’interface USB permettant de le programmer on s’en sort pour moins de 2€ en théorie. En réalité on se rapproche plus des 3€ dans la conjoncture actuelle ce qui reste vraiment très abordable.

Première prise en main

SDK

Ressources

Publié dans Non classé | Marqué avec , , | 3 commentaires

Rhaaa python :

In [6]: hex(1<<31)                                                                                                                                                                                                 
Out[6]: '0x80000000'

In [7]: hex(1<<31 + 1)                                                                                                                                                                                             
Out[7]: '0x100000000'
Langage du code : JavaScript (javascript)

Le décalage binaire est moins prioritaire que l’addition. Noubliez pas les parenthèses :

In [8]: hex((1<<31) + 1)                                                                                                                                                                                           
Out[8]: '0x80000001'Langage du code : JavaScript (javascript)

Publié le par admin | Laisser un commentaire

Rust sur RP2040

Dans la continuité de la LED clignotante sur Longan Nano, pourquoi ne pas tester sur RP2040 puisque j’en ai une dans mon étagère ? En plus, il existe un projet tout prêt pour ça.

Alors allons y. On clone d’abord le projet :

$ git clone https://github.com/eterevsky/rp2040-blink.git
$ cd rp2040-blink/Langage du code : PHP (php)

On installe la chaîne de développement rust pour le RP2040 (Arm cortex-m0 et tous les trucs elf2uf2-rs):

$ rustup target install thumbv6m-none-eabi
info: downloading component 'rust-std' for 'thumbv6m-none-eabi'
info: installing component 'rust-std' for 'thumbv6m-none-eabi'
$ cargo install --locked elf2uf2-rs
    Updating crates.io index
  Downloaded elf2uf2-rs v1.3.7
  Downloaded 1 crate (51.1 KB) in 0.52s
  Installing elf2uf2-rs v1.3.7
warning: package `crossbeam-utils v0.8.5` in Cargo.lock is yanked in registry `crates-io`, consider running without --locked
...
   Compiling elf2uf2-rs v1.3.7
    Finished release [optimized] target(s) in 2m 06s
  Installing /home/fabien/.cargo/bin/elf2uf2-rs
   Installed package `elf2uf2-rs v1.3.7` (executable `elf2uf2-rs`)
Langage du code : JavaScript (javascript)

Enfin on connecte la carte sur l’USB en laissant le bouton «BOOTSEL» appuyé pour lancer la compilation de l’exemple avec cargo:

$ cargo run --release
    Updating crates.io index
  Downloaded debug-helper v0.3.13
...
  Compiling rp2040-hal v0.3.0
    Finished release [optimized] target(s) in 41.66s
     Running `elf2uf2-rs -d -s target/thumbv6m-none-eabi/release/blink`
Found pico uf2 disk /media/fabien/RPI-RP2
Transfering program to pico
61.50 KB / 61.50 KB [=======================================================================================================================================================================] 100.00 % 122.27 KB/s 
Found pico serial on /dev/ttyACM0
Langage du code : JavaScript (javascript)

Chez moi ça se bloque dans cet état. Pour lancer le programme il faut débrancher puis rebrancher la carte et … la LED clignote !

Alors, tout comme pour la Longan Nano, je dois dire que l’installation et l’utilisation des outils de crosscompilation et de téléchargement est géniale ! C’est très rapide, ça s’installe en très peu de commande. Et visiblement c’est complètement cross-platforme puisque la doc du projet de led clignotant indique que ça n’avait pas été testé sous Linux mais seulement W$ et pomme.

Par contre pour le moment nous n’avons pas vu une once de code rust. Il est temps de fourrer notre groin dans le code d’exemple pour pacifier un peu le clignotement de cette led.

Codons mon bon

Allumé, éteint, allumé, éteint, … c’est un peu violent. Voyons si nous pouvons faire quelque chose de plus progressif pour avoir un clignotement doux. Le code d’exemple est nettement plus long que celui que nous avions sur la Longan Nano. La raison principale étant que le programme intègre la gestion de l’USB en plus de la simple LED clignotante.

Pas besoin d’avoir des milliers d’heures de pratique pour trouver la boucle de clignotement cependant :

    loop {
        led_pin.set_high().unwrap();
        write!(usb, "On\n").unwrap();
        delay.delay_ms(500);

        led_pin.set_low().unwrap();
        write!(usb, "Off\n").unwrap();
        delay.delay_ms(500);
    }Langage du code : JavaScript (javascript)

Les macro «write!()» permettent d’écrire du texte sur le port uart émulé par l’usb.

À partir de là il est assez simple de modifier cette partie pour faire du soft-blink. Comme pour la Longan Nano, la documentation de la cagette cortex_m nous indique qu’il existe une manière d’attendre les µs : delay_us(). Le code va donc ressembler à s’y méprendre à celui de la Longan Nano :

    let count_max:u32 = 1000;
    let mut count:u32 = 0;
    let mut decount: bool = true;

    loop {
        // on
        led_pin.set_high().unwrap();
        delay.delay_us(count);
        // off
        led_pin.set_low().unwrap();
        delay.delay_us(count_max - count);
        if decount {
            if count == 0 {
                decount = false;
            } else {
                count = count - 1;
            }
        } else {
            if count < count_max {
                count = count + 1;
            }else{
                decount = true;
            }
        }
    }
Langage du code : JavaScript (javascript)

On prendra bien soin de virer les messages on/off qui ralentissent prodigieusement le comptage du clignotement doux.

Et la LED clignote

Voila \o/

Pour conclure

Encore une fois, la mise en œuvre des outils pour programmer en Rust sur un microcontrôleur est d’une incroyable facilité et rapidité. Deux trois lignes de commandes (et un projet github qui va bien quand même 😉 et c’est plié !

Je suis encore très loin de maîtriser le langage, mais il m’a été extrêmement facile de trouver la bonne documentation pour avoir la fonction qui va bien de manière à améliorer l’exemple et faire un minimum «joujou» avec la machine.

Publié dans Non classé | Marqué avec , , , , | Laisser un commentaire

Rust sur Longan Nano

La Longan Nano est une petite carte de la taille d’un pouce munie d’un microcontrôleur à cœur RISC-V le GD32VF103CBT6. Processeur qui est un clone du fameux stm32 de chez ST, MAIS avec un cœur RISC-V (alors que le stm32 est à base de ARM).

Ce qui est bien avec la Longan Nano c’est que pour $4.90 il y a absolument tout pour faire du développement embarqué: en plus de l’écran oled couleurs et la LED RGB il y a une interface USB (connecteur usb-c) qui permet d’alimenter la carte, la programmer et communiquer par UART. Pour le JTAG par contre il faut un adaptateur externe qui peut cependant être très pratique pour utiliser un debugger.

Ce qui est moins bien par contre c’est qu’elle semble en rupture de stock depuis longtemps.

Bref, c’est une «vieille» carte mais qui est parfaite pour faire du développement embarqué sans rien d’autre qu’un PC et un câble USB.

Pourquoi ne pas tenter de faire du Rust avec alors ? En plus il semble exister des projets de support du langage pour cette carte. Voila qui pourrait démystifier rust pour l’embarqué !

Codons mon bon

La documentation officielle de la cagette nous demande de vérifier la version de rust :

$ rustup default stable
info: using existing install for 'stable-x86_64-unknown-linux-gnu'
info: default toolchain set to 'stable-x86_64-unknown-linux-gnu'

  stable-x86_64-unknown-linux-gnu unchanged - rustc 1.58.0 (02072b482 2022-01-11)
Langage du code : JavaScript (javascript)

Version 1.58, c’est bon on est supérieur à la 1.36 requise. Comme je veux travailler avec juste le câble usb j’utiliserais (ou tenterais d’utiliser) dfu-util pour programmer le micro.

Il faut juste se compiler une version des binutils comme indiqué dans la doc pour avoir l’utilitaire objcopy :

$ git clone https://github.com/sifive/riscv-binutils-gdb.git
$ cd riscv-binutils-gdb
$ ./configure --target=riscv64-unknown-elf --disable-werror --with-python=no --disable-gdb --disable-sim --disable-libdecnumber --disable-libreadline --with-expat=yes --with-mpc=no --with-mpfr=no --with-gmp=no
$ makeLangage du code : JavaScript (javascript)

Ça prend un peut de temps avec ma vieille machine (T430) mais ça marche.

On aura également besoin d’une toolchain riscv:

$ wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.1.0-2019.01.0-x86_64-linux-ubuntu14.tar.gz
$ tar zxvf riscv64-unknown-elf-gcc-8.1.0-2019.01.0-x86_64-linux-ubuntu14.tar.gzLangage du code : JavaScript (javascript)

Et bien entendu, il faudra «descendre» le projet git hub d’exemples:

$ git clone https://github.com/riscv-rust/longan-nano.git
$ cd longan-nano
$ rustup target add riscv32imac-unknown-none-elfLangage du code : PHP (php)

Puisque visiblement j’ai une version B du microcontrôleur il faut modifier le fichier de configuration .cargo/config.

Et c’est parti mamie :

$ cargo build --examples --release --all-features

On extrait maintenant l’huile essentiel de notre binaire avec objcopy que l’on appelera firmware.bin :

../riscv64-unknown-elf-gcc-8.1.0-2019.01.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-objcopy -O binary target/riscv32imac-unknown-none-elf/release/examples/blinky firmware.bin

Puis on le télécharge dans la carte au moyen de dfu-util en ayant bien pris soin de mettre le microcontrôleur en mode «bootstrap» ( appui sur reset tout en gardant boot0 pressé).

$  dfu-util -a 0 -s 0x08000000:leave -D firmware.bin
dfu-util 0.10-dev

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Warning: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release
dfu-util: Cannot open DFU device 0a5c:21e6 found on devnum 3 (LIBUSB_ERROR_ACCESS)
Opening DFU capable USB device...
Device ID 28e9:0189
Device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "Internal Flash  "
Found GD32VF103, which reports a bad page size and count for its internal memory.
Fixed layout based on part number: page size 1024, count 128.
Downloading element to address = 0x08000000, size = 9388
Erase   	[=========================] 100%         9388 bytes
Erase    done.
Download	[=========================] 100%         9388 bytes
Download done.
File downloaded successfully

Et la led clignote \o/ !

Le code

Le code à proprement parler du clignotement de led est donné dans le fichier examples/blinky.rs

Et le cœur de la boucle de clignotement est donnée ci-dessous :

    let mut i = 0;
    loop {
        let inext = (i + 1) % leds.len();
        leds[i].off();
        leds[inext].on();
        delay.delay_ms(500);

        i = inext;
    }Langage du code : JavaScript (javascript)

Il y a trois leds (RGB), on se sert de l’index i pour parcourir le tableau de leds. On éteint la led courante puis on allume la suivante et on attend 500ms.

De cette manière, la led va changer de couleur toutes les demi-seconde et nous offrir un clignotement tricolore.

Si l’on trouve le clignotement on/off un peu trop violent, on peut, comme exercice faire en sorte que la couleurs s’allume et s’éteigne progressivement avec un code de ce genre :

    leds[0].off();
    leds[1].off();
    leds[2].off();

    let count_max:u32 = 1000;
    let mut count:u32 = 0;
    let mut decount: bool = true;
    let mut i:usize = 0;

    loop {
        leds[i].on();
        delay.delay_us(count);
        leds[i].off();
        delay.delay_us(count_max - count);
        if decount {
            if count == 0 {
                decount = false;
                i = (i + 1) % leds.len();
            } else {
                count = count - 1;
            }
        } else {
            if count < count_max {
                count = count + 1;
            }else{
                decount = true;
            }
        }
    }Langage du code : JavaScript (javascript)

On aura bien pris soin de descendre la granularité du délais à la microseconde puisque c’est disponible dans le HAL du microcontrôleur (GD32VF103).

Voila un clignotement plus doux des LEDs. Et on se rend compte par la même occasion que la LED verte est nettement plus puissante que les deux autres.

Il y a d’autres exemples dans le git du projet, notamment pour utiliser le lecteur microSD ainsi que l’écran, mais je laisse le soin au lecteur de les découvrir par lui même 😉

Pour conclure, grâce à ce projet, la prise en main de la Longan Nano avec du Rust est vraiment simple et très peu verbeuse. J’avais eu beaucoup plus de mal à la prendre en main en C avec tout le bazar de platformio et vscode à l’époque. Mais c’est peut-être tout simplement parce que la carte est plus mature aujourd’hui aussi 😉

Ressources

Publié dans Non classé | Marqué avec , , | 2 commentaires