{"id":2301,"date":"2012-06-04T08:00:03","date_gmt":"2012-06-04T07:00:03","guid":{"rendered":"http:\/\/www.blaess.fr\/christophe\/?p=2301"},"modified":"2012-06-04T08:00:03","modified_gmt":"2012-06-04T07:00:03","slug":"gpio-pandaboard-et-temps-reel-5-le-multiplexage-des-gpio","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2012\/06\/04\/gpio-pandaboard-et-temps-reel-5-le-multiplexage-des-gpio\/","title":{"rendered":"GPIO, Pandaboard et temps r\u00e9el &#8211; 5 &#8211; Le multiplexage des GPIO"},"content":{"rendered":"<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-2445\" title=\"Cliquer pour agrandir\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-04.jpg\" alt=\"Pandaboard, GPIO et temps r\u00e9el\" width=\"150\" height=\"201\" \/><\/a><\/p>\n<p style=\"padding-left: 30px; text-align: justify;\">Suite \u00e0 <a title=\"http:\/\/www.blaess.fr\/christophe\/2012\/05\/21\/gpio-pandaboard-et-temps-reel-3-lecture-sur-des-entrees\/#comment-1529\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/05\/21\/gpio-pandaboard-et-temps-reel-3-lecture-sur-des-entrees\/#comment-1529\">un petit commentaire de Yoann Sculo<\/a> concernant l&rsquo;<a title=\"GPIO, Pandaboard et temps r\u00e9el \u2013 3 \u2013 Lecture sur des entr\u00e9es\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/05\/21\/gpio-pandaboard-et-temps-reel-3-lecture-sur-des-entrees\/\">avant dernier article<\/a>, j&rsquo;ai eu envie de d\u00e9tailler un peu le fonctionnement du multiplexage des GPIO sur un processeur OMAP (comme celui de la Pandaboard), et les param\u00e8tres auxquels nous pouvons avoir acc\u00e8s par l&rsquo;interm\u00e9diaire du syst\u00e8me de fichiers <code>debugfs<\/code>.<\/p>\n<p>\n<!--more-->\n<\/p>\n<h1>Multiplexage des GPIO de l&rsquo;OMAP<\/h1>\n<p style=\"text-align: justify; padding-left: 60px;\">Pour obtenir des informations d\u00e9taill\u00e9es sur le fonctionnement de l&rsquo;OMAP 4430 (celui utilis\u00e9 dans la Pandaboard), il ne faut pas h\u00e9siter \u00e0 se reporter au <a title=\"OMAP 4430 TRM \" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-06-04\/OMAP4430-TRM.pdf\">TRM<\/a> (<em>Technical Reference Manual<\/em>) diffus\u00e9 par Texas Instruments quitte \u00e0 prendre un peu de temps pour se familiariser avec l&rsquo;organisation de ses 5554 pages&nbsp;!<\/p>\n<p style=\"text-align: justify;\">Les processeurs de la famille OMAP proposent un nombre beaucoup plus important de lignes logiques de GPIO que le nombre de broches physiquement disponibles sur leurs bo\u00eetiers. Aussi un multiplexage est-il n\u00e9cessaire pour s\u00e9lectionner quelle fonctionnalit\u00e9 est affect\u00e9e \u00e0 chaque broche \u00e0 un instant donn\u00e9.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-221.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2342\" title=\"Broche 10 du connecteur d'extension A\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-221.jpg\" alt=\"Broche 10 du connecteur d'extension A\" width=\"600\" height=\"200\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Prenons l&rsquo;exemple de la broche 10 du connecteur J3 que nous avons d\u00e9j\u00e0 employ\u00e9e \u00e0 plusieurs reprises. En examinant <a title=\"Panda_Board_Spec_REVEA1_04.pdf\" href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2012-05-10\/Panda_Board_Spec_REVEA1_04.pdf\">la documentation de la Pandaboard<\/a>, nous avons vu que trois fonctions lui sont attribu\u00e9es&nbsp;: <code>MCSPI1_CS<\/code> (<em>Chip Select<\/em> du bus SPI1), <code>UART1_RX<\/code> (ligne de r\u00e9ception du port s\u00e9rie num\u00e9ro 1) et <code>GPIO_138<\/code>. C&rsquo;est cette derni\u00e8re fonction que nous avons employ\u00e9e dans les articles pr\u00e9c\u00e9dents.<\/p>\n<p style=\"text-align: justify;\">Le choix entre ces trois fonctions est fait tout d&rsquo;abord par le <em>bootloade<\/em>r (U-boot), comme nous l&rsquo;avons vu dans l&rsquo;<a title=\"GPIO, Pandaboard et temps r\u00e9el \u2013 3 \u2013 Lecture sur des entr\u00e9es\" href=\"http:\/\/www.blaess.fr\/christophe\/2012\/05\/21\/gpio-pandaboard-et-temps-reel-3-lecture-sur-des-entrees\/\">avant-dernier article<\/a>. Ensuite, le noyau Linux lui-m\u00eame affecte les broches qui le concernent. Toutefois, il nous est possible d&rsquo;intervenir sur le param\u00e9trage depuis l&rsquo;espace utilisateur.<\/p>\n<p style=\"text-align: justify;\">Chaque broche peut th\u00e9oriquement avoir jusqu&rsquo;\u00e0 huit fonctions. \u00c0 un moment donn\u00e9, une broche est configur\u00e9e suivant un <em>mode<\/em>, et le processeur OMAP propose donc les modes 0 \u00e0 7. Par exemple, sur la Pandaboard la broche 10 du connecteur J3 peut \u00eatre configur\u00e9e avec les modes suivants&nbsp;:<\/p>\n<ul>\n<li>Mode 0&nbsp;: <code>MCSPI1_CS<\/code><\/li>\n<li>Mode 1&nbsp;: <code>UART1_RX<\/code><\/li>\n<li>Mode 2&nbsp;: Non utilis\u00e9<\/li>\n<li>Mode 3&nbsp;: <code>GPIO_138<\/code><\/li>\n<li>Mode 4 \u00e0 6&nbsp;: Non utilis\u00e9s<\/li>\n<li style=\"text-align: justify;\">Mode 7&nbsp;: <em>Safe mode<\/em> : la broche est isol\u00e9e, les contacts \u00e9ventuels avec d&rsquo;autres broches ne provoqueront pas de court-circuit.<\/li>\n<\/ul>\n<h1>Consultation avec <code>debugfs<\/code><\/h1>\n<p style=\"text-align: justify;\">Le syst\u00e8me de fichiers <code>debugfs<\/code> est, comme son nom l&rsquo;indique, destin\u00e9 \u00e0 aider \u00e0 la mise au point du noyau. Il s&rsquo;agit d&rsquo;un syst\u00e8me de fichiers virtuel, comme ceux que l&rsquo;on monte sur <code>\/proc<\/code> ou <code>\/sys<\/code>, mais les r\u00e8gles d&rsquo;utilisation sont beaucoup plus souples qu&rsquo;avec ces derniers (<code>\/proc<\/code> est r\u00e9serv\u00e9 aux processus et aux param\u00e8tres de fonctionnement du noyau, <code>\/sys<\/code> contient la repr\u00e9sentation du syst\u00e8me vu du kernel en fournissant une unique valeur par fichier).<\/p>\n<p style=\"text-align: justify;\">Bien que l&rsquo;on puisse choisir un autre r\u00e9pertoire, on convient g\u00e9n\u00e9ralement de monter (dans un script de d\u00e9marrage ou dans le fichier <code>\/etc\/fstab<\/code>) le syst\u00e8me <code>debugfs<\/code> sur le r\u00e9pertoire <code>\/sys\/kernel\/debug<\/code>.<\/p>\n<p style=\"text-align: justify;\">En voici un exemple sur la Pandaboard&nbsp;:<\/p>\n<pre>[Panda]# <strong>mount none \/sys\/kernel\/debug\/ -t debugfs<\/strong>\n[Panda]# <strong>cd \/sys\/kernel\/debug\/<\/strong>\n[Panda]# <strong>ls<\/strong>\nbdi        gpio  ieee80211  mmc0      regulator       tracing    voltage\nbluetooth  hid   memblock   omap_mux  sched_features  usb\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Nous pouvons examiner dans le fichier <code>gpio<\/code> la configuration actuelle des GPIO employ\u00e9s par le syst\u00e8me.<\/p>\n<pre>[Panda]# <strong>cat gpio<\/strong>\nGPIOs 0-31, gpio:\n gpio-1   (hub_power           ) out hi\n gpio-7   (pandaboard::status1 ) out lo\n gpio-8   (pandaboard::status2 ) out lo\n\nGPIOs 32-63, gpio:\n gpio-62  (hub_nreset          ) out hi\n\nGPIOs 64-95, gpio:\n\nGPIOs 96-127, gpio:\n\nGPIOs 128-159, gpio:\n\nGPIOs 160-191, gpio:\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Nous voyons qu&rsquo;il y a six contr\u00f4leurs, chacun g\u00e9rant 32 GPIO, ce qui est confirm\u00e9 par le <em>Technical Reference Manual<\/em> de l&rsquo;OMAP. Ceci correspond aux entr\u00e9es <code>gpiochip<\/code> que nous trouvons dans le r\u00e9pertoire <code>\/sys\/class\/gpio<\/code>.<\/p>\n<pre>[Panda]# <strong>ls \/sys\/class\/gpio\/<\/strong>\nexport       gpio62       gpiochip128  gpiochip32   gpiochip96\ngpio1        gpiochip0    gpiochip160  gpiochip64   unexport\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Le GPIO 1 correspond \u00e0 l&rsquo;alimentation du bloc Ethernet + USB de la Pandaboard, ainsi une commande.<\/p>\n<pre>[Panda]# <strong>echo 0 &gt; \/sys\/class\/gpio\/gpio1\/value<\/strong><\/pre>\n<p style=\"text-align: justify;\">\u00e9teint-elle ce hub (et coupe par la m\u00eame occasion ma connexion sur la Pandaboard puisque j&rsquo;y acc\u00e8de par <em>ssh<\/em>, ce qui m&rsquo;oblige \u00e0 r\u00e9initialiser la carte&nbsp;!).<\/p>\n<p style=\"text-align: justify;\">Les GPIO 7 et 8 sont utilis\u00e9s pour les LEDs d&rsquo;\u00e9tat de la Pandaboard (voir <a title=\"Signes de vie d\u2019un syst\u00e8me embarqu\u00e9\" href=\"http:\/\/www.blaess.fr\/christophe\/2011\/07\/15\/signes-de-vie-dun-systeme-embarque\/\">cet article<\/a>), et le 62 permet de r\u00e9initialiser le contr\u00f4leur USB\/Ethernet.<\/p>\n<p style=\"text-align: justify;\">Examinons le contenu du r\u00e9pertoire <code>omap_mux<\/code>, qui concerne le multiplexage des sorties de l&rsquo;OMAP.<\/p>\n<pre>[Panda]# <strong>cd omap_mux\/<\/strong>\n[Panda]# <strong>ls<\/strong>\nabe_clks         csi22_dy1       gpmc_a19       gpmc_ncs7      kpd_row2     sim_pwrctrl          usbb1_ulpitll_clk\nabe_dmic_clk1    dpm_emu0        gpmc_a20       gpmc_noe       kpd_row3     sim_reset            usbb1_ulpitll_dat0\nabe_dmic_din1    dpm_emu1        gpmc_a21       gpmc_nwe       kpd_row4     sr_scl               usbb1_ulpitll_dat1\nabe_dmic_din2    dpm_emu10       gpmc_a22       gpmc_nwp       kpd_row5     sr_sda               usbb1_ulpitll_dat2\nabe_dmic_din3    dpm_emu11       gpmc_a23       gpmc_wait0     mcspi1_clk   sys_32k              usbb1_ulpitll_dat3\nabe_mcbsp1_clkx  dpm_emu12       gpmc_a24       gpmc_wait1     mcspi1_cs0   sys_boot0            usbb1_ulpitll_dat4\nabe_mcbsp1_dr    dpm_emu13       gpmc_a25       gpmc_wait2     mcspi1_cs1   sys_boot1            usbb1_ulpitll_dat5\nabe_mcbsp1_dx    dpm_emu14       gpmc_ad0       hdmi_cec       mcspi1_cs2   sys_boot2            usbb1_ulpitll_dat6\nabe_mcbsp1_fsx   dpm_emu15       gpmc_ad1       hdmi_ddc_scl   mcspi1_cs3   sys_boot3            usbb1_ulpitll_dat7\nabe_mcbsp2_clkx  dpm_emu16       gpmc_ad10      hdmi_ddc_sda   mcspi1_simo  sys_boot4            usbb1_ulpitll_dir\nabe_mcbsp2_dr    dpm_emu17       gpmc_ad11      hdmi_hpd       mcspi1_somi  sys_boot5            usbb1_ulpitll_nxt\nabe_mcbsp2_dx    dpm_emu18       gpmc_ad12      hdq_sio        mcspi4_clk   sys_boot6            usbb1_ulpitll_stp\nabe_mcbsp2_fsx   dpm_emu19       gpmc_ad13      i2c1_scl       mcspi4_cs0   sys_boot7            usbb2_hsic_data\nabe_pdm_dl_data  dpm_emu2        gpmc_ad14      i2c1_sda       mcspi4_simo  sys_nirq1            usbb2_hsic_strobe\nabe_pdm_frame    dpm_emu3        gpmc_ad15      i2c2_scl       mcspi4_somi  sys_nirq2            usbb2_ulpitll_clk\nabe_pdm_lb_clk   dpm_emu4        gpmc_ad2       i2c2_sda       sdmmc1_clk   sys_nrespwron        usbb2_ulpitll_dat0\nabe_pdm_ul_data  dpm_emu5        gpmc_ad3       i2c3_scl       sdmmc1_cmd   sys_nreswarm         usbb2_ulpitll_dat1\nboard            dpm_emu6        gpmc_ad4       i2c3_sda       sdmmc1_dat0  sys_pwr_req          usbb2_ulpitll_dat2\ncam_globalreset  dpm_emu7        gpmc_ad5       i2c4_scl       sdmmc1_dat1  sys_pwron_reset_out  usbb2_ulpitll_dat3\ncam_shutter      dpm_emu8        gpmc_ad6       i2c4_sda       sdmmc1_dat2  uart2_cts            usbb2_ulpitll_dat4\ncam_strobe       dpm_emu9        gpmc_ad7       jtag_ntrst     sdmmc1_dat3  uart2_rts            usbb2_ulpitll_dat5\ncsi21_dx0        fref_clk0_out   gpmc_ad8       jtag_rtck      sdmmc1_dat4  uart2_rx             usbb2_ulpitll_dat6\ncsi21_dx1        fref_clk1_out   gpmc_ad9       jtag_tck       sdmmc1_dat5  uart2_tx             usbb2_ulpitll_dat7\ncsi21_dx2        fref_clk2_out   gpmc_clk       jtag_tdi       sdmmc1_dat6  uart3_cts_rctx       usbb2_ulpitll_dir\ncsi21_dx3        fref_clk3_out   gpmc_nadv_ale  jtag_tdo       sdmmc1_dat7  uart3_rts_sd         usbb2_ulpitll_nxt\ncsi21_dx4        fref_clk3_req   gpmc_nbe0_cle  jtag_tms_tmsc  sdmmc5_clk   uart3_rx_irrx        usbb2_ulpitll_stp\ncsi21_dy0        fref_clk4_out   gpmc_nbe1      kpd_col0       sdmmc5_cmd   uart3_tx_irtx        usbc1_icusb_dm\ncsi21_dy1        fref_clk4_req   gpmc_ncs0      kpd_col1       sdmmc5_dat0  uart4_rx             usbc1_icusb_dp\ncsi21_dy2        fref_clk_ioreq  gpmc_ncs1      kpd_col2       sdmmc5_dat1  uart4_tx\ncsi21_dy3        fref_slicer_in  gpmc_ncs2      kpd_col3       sdmmc5_dat2  usba0_otg_ce\ncsi21_dy4        fref_xtal_in    gpmc_ncs3      kpd_col4       sdmmc5_dat3  usba0_otg_dm\ncsi22_dx0        gpmc_a16        gpmc_ncs4      kpd_col5       sim_cd       usba0_otg_dp\ncsi22_dx1        gpmc_a17        gpmc_ncs5      kpd_row0       sim_clk      usbb1_hsic_data\ncsi22_dy0        gpmc_a18        gpmc_ncs6      kpd_row1       sim_io       usbb1_hsic_strobe\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Par convention, les ports du processeur OMAP sont nomm\u00e9s en utilisant leur fonction premi\u00e8re, celle du Mode 0. Ainsi la broche 10 de connecteur J3 est-elle nomm\u00e9e <code>mcspi1_cs1<\/code>.<\/p>\n<pre>[Panda]# <strong>cat mcspi1_cs1 <\/strong>\nname: mcspi1_cs1.gpio_138 (0x4a10013a\/0x13a = 0x010b), b af23, t NA\nmode: OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE3\nsignals: mcspi1_cs1 | uart1_rx | NA | gpio_138 | NA | NA | NA | safe_mode\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Les signaux possibles pour cette broche sont d\u00e9crits sur la ligne \u00ab\u00a0<code>signals:<\/code>\u00a0\u00bb et correspondent \u00e0 la liste observ\u00e9e plus haut. La ligne \u00ab\u00a0<code>mode:<\/code>\u00a0\u00bb indique la configuration actuelle. Ici, le mode s\u00e9lectionn\u00e9 est Mode_3 (<code>gpio_138<\/code>) configur\u00e9 en entr\u00e9e avec une r\u00e9sistance de rappel \u00e0 la masse (<em>pulldown<\/em>).<\/p>\n<h1 style=\"text-align: justify;\">Param\u00e9trage depuis l&rsquo;espace utilisateur<\/h1>\n<p style=\"text-align: justify;\">Nous pouvons modifier les param\u00e8tres pr\u00e9sent\u00e9s par <code>debugfs<\/code>. Pour cela il faut \u00e9crire dans le fichier une valeur sur deux octets qui se compose ainsi.<\/p>\n<ul>\n<li style=\"text-align: justify;\">Bits 0, 1 et 2&nbsp;: num\u00e9ro de mode<\/li>\n<li style=\"text-align: justify;\">Bit 3&nbsp;: activation de la r\u00e9sistance de rappel en entr\u00e9e<\/li>\n<li style=\"text-align: justify;\">Bit 4&nbsp;: r\u00e9sistance de rappel vers le haut (<em>pull-up<\/em>).<\/li>\n<li style=\"text-align: justify;\">Bit 5-7&nbsp;: inutilis\u00e9s<\/li>\n<li style=\"text-align: justify;\">Bit 8&nbsp;: broche en entr\u00e9e<\/li>\n<li style=\"text-align: justify;\">Bit 9-15&nbsp;: configuration de l&rsquo;\u00e9tat de la broche lors de la mise en sommeil (non d\u00e9taill\u00e9e ici)<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-01.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2319\" title=\"Configuration du multiplexeur Omap\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-01.png\" alt=\"Configuration du multiplexeur Omap\" width=\"600\" height=\"161\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Modifions ces param\u00e8tres, en conservant le mode 3 (celui du GPIO).<\/p>\n<h3 style=\"text-align: justify;\">Basculement en sortie<\/h3>\n<p style=\"text-align: justify;\">Il faut d\u00e9sactiver les bits <code>Input_enable<\/code>, <code>Pull_enable<\/code> et calculer le mode d\u00e9sir\u00e9.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-02.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2320\" title=\"Multiplexeur en sortie\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-02.png\" alt=\"Multiplexeur en sortie\" width=\"600\" height=\"65\" \/><\/a>Nous allons donc \u00e9crire la valeur <code>0x0003<\/code>.<\/p>\n<pre>[Panda]# <strong>echo 0x0003 &gt; mcspi1_cs1<\/strong>\n[Panda]# <strong>cat mcspi1_cs1<\/strong>\nname: mcspi1_cs1.gpio_138 (0x4a10013a\/0x13a = 0x0003), b af23, t NA\nmode: OMAP_PIN_OUTPUT | OMAP_MUX_MODE3\nsignals: mcspi1_cs1 | uart1_rx | NA | gpio_138 | NA | NA | NA | safe_mode\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">La ligne \u00ab\u00a0<code>mode:<\/code>\u00a0\u00bb a bien \u00e9t\u00e9 modifi\u00e9e pour afficher <code>OMAP_PIN_OUTPUT<\/code>.<\/p>\n<h3 style=\"text-align: justify;\">Basculement en entr\u00e9e simple<\/h3>\n<p style=\"text-align: justify;\">Pour ramener notre broche en entr\u00e9e, nous activons le bit <code>Input_enable<\/code>.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-03.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2321\" title=\"Multiplexeur en entr\u00e9e simple\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-03.png\" alt=\"Multiplexeur en entr\u00e9e simple\" width=\"600\" height=\"65\" \/><\/a>La valeur calcul\u00e9e est <code>0x0103<\/code><\/p>\n<pre>[Panda]# <strong><code>echo 0x0103 &gt; mcspi1_cs1<\/code><\/strong>\n[Panda]# <strong><code>cat mcspi1_cs1 <\/code><\/strong>\nname: mcspi1_cs1.gpio_138 (0x4a10013a\/0x13a = 0x0103), b af23, t NA\nmode: OMAP_PIN_INPUT | OMAP_MUX_MODE3\nsignals: mcspi1_cs1 | uart1_rx | NA | gpio_138 | NA | NA | NA | safe_mode\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Aucun <em>pull-up<\/em> ou <em>pull-down<\/em> n&rsquo;\u00e9tant activ\u00e9, la valeur lue en entr\u00e9e peut fluctuer si elle n&rsquo;est pas connect\u00e9e. Par exemple les lignes suivantes<\/p>\n<pre>[Panda]# <strong>echo 138 &gt; \/sys\/class\/gpio\/export<\/strong>\n[Panda]# <strong>while true; do cat \/sys\/class\/gpio\/gpio138\/value ; done<\/strong><\/pre>\n<p style=\"text-align: justify;\">affichent une alternance de valeurs 0 et 1 qui \u00e9voluent si on effleure du doigt la broche 10 (ce que je ne conseille pas, des tensions \u00e9lev\u00e9es engendr\u00e9es par l&rsquo;\u00e9lectricit\u00e9 statique pouvant endommager le processeur).<\/p>\n<h3 style=\"text-align: justify;\">Basculement en entr\u00e9e avec rappel \u00e0 la masse (<em>pull-down<\/em>)<\/h3>\n<p style=\"text-align: justify;\">Pour activer un <em>pull-down<\/em>, il suffit d&rsquo;activer le bit <code>Pull_enable<\/code> en laissant le bit <code>Pull_up<\/code> d\u00e9sactiv\u00e9. Il s&rsquo;agit de la configuration fix\u00e9e par d\u00e9faut par le <em>bootloader<\/em> U-boot.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-04.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2322\" title=\"Multiplexeur en entr\u00e9e pull-down\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-04.png\" alt=\"Multiplexeur en entr\u00e9e pull-down\" width=\"600\" height=\"65\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">La valeur \u00e0 \u00e9crire est <code>0x010B<\/code><\/p>\n<pre>[Panda]# <strong>echo 0x010B &gt; mcspi1_cs1 <\/strong>\n[Panda]# <strong>cat mcspi1_cs1 <\/strong>\nname: mcspi1_cs1.gpio_138 (0x4a10013a\/0x13a = 0x010b), b af23, t NA\nmode: OMAP_PIN_INPUT_PULLDOWN | OMAP_MUX_MODE3\nsignals: mcspi1_cs1 | uart1_rx | NA | gpio_138 | NA | NA | NA | safe_mode\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Nous pouvons v\u00e9rifier l&rsquo;\u00e9tat de l&rsquo;entr\u00e9e. Cette fois la valeur est fig\u00e9e, m\u00eame si l&rsquo;entr\u00e9e est laiss\u00e9e non connect\u00e9e et si on l&rsquo;effleure du doigt.<\/p>\n<pre>[Panda]# <strong>cat \/sys\/class\/gpio\/gpio138\/value <\/strong>\n0\n[Panda]#<\/pre>\n<h3 style=\"text-align: justify;\">Basculement en entr\u00e9e avec tirage \u00e0 la tension d&rsquo;alimentation (<em>pull-up<\/em>)<\/h3>\n<p style=\"text-align: justify;\">Enfin, nous allons modifier la r\u00e9sistance de rappel en activant un <em>pull-up<\/em> vers la tension d&rsquo;alimentation gr\u00e2ce au bit <code>Pull_up<\/code>.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-05.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2323\" title=\"Multiplexeur en entr\u00e9e pull-up\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/MUX-05.png\" alt=\"Multiplexeur en entr\u00e9e pull-up\" width=\"600\" height=\"65\" \/><\/a>La valeur obtenue est <code>0x011B<\/code>.<\/p>\n<pre>[Panda]# <strong>echo 0x011B &gt; mcspi1_cs1 <\/strong>\n[Panda]# <strong>cat mcspi1_cs1<\/strong>\nname: mcspi1_cs1.gpio_138 (0x4a10013a\/0x13a = 0x011b), b af23, t NA\nmode: OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE3\nsignals: mcspi1_cs1 | uart1_rx | NA | gpio_138 | NA | NA | NA | safe_mode\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">\u00c0 pr\u00e9sent l&rsquo;entr\u00e9e (toujours non connect\u00e9e) ne pr\u00e9sente plus la m\u00eame valeur.<\/p>\n<pre>[Panda]# <strong>cat \/sys\/class\/gpio\/gpio138\/value <\/strong>\n1\n[Panda]#<\/pre>\n<h1>Changement de mode sur une broche<\/h1>\n<p style=\"text-align: justify;\">Nous pouvons choisir de modifier le mode de fonctionnement d&rsquo;une broche du port d&rsquo;extension A. Il n&rsquo;est pas facile de savoir comment les broches sont configur\u00e9es par d\u00e9faut, car la documentation de la Pandaboard est un peu\u00a0 floue sur ce sujet. Voici donc un petit script shell qui nous affiche pour chaque broche (identifi\u00e9e par son num\u00e9ro et son nom officiel) la configuration actuelle ainsi que la liste des configurations possibles.<\/p>\n<pre><strong>\/root\/liste-j3.sh:<\/strong>\n#\/bin\/sh\n\ncd \/sys\/kernel\/debug\/omap_mux\nnum=3\nfor name in gpmc_ad7 mcspi1_cs3 gpmc_ad6 uart4_tx gpmc_ad5 uart4_rx gpmc_ad4 mcspi1_cs1 gpmc_ad3 mcspi1_simo gpmc_ad2 mcspi1_cs2 gpmc_ad1 mcspi1_cs0 gpmc_ad0 mcspi1_somi gpmc_nwe mcspi1_clk gpmc_noe gpmc_ad15 i2c4_sda i2c4_scl\ndo\n  mode=$(grep \"^mode:\" \"${name}\" | sed 's\/.*OMAP_MUX_MODE\/\/')\n  list=$(grep \"^signals:\" \"${name}\" | sed 's\/^signals:\/\/; s\/|\/\/g')\n  item=0\n  for i in ${list}\n  do\n    if [ ${item} -eq ${mode} ]\n    then\n      selected_function=$i\n      break;\n    fi\n    item=$((item + 1))\n  done\n  echo \"${num} ${name} ${mode} ${selected_function} (${list})\"\n  num=$((num + 1))\ndone<\/pre>\n<p style=\"text-align: justify;\">A l&rsquo;ex\u00e9cution, nous obtenons une liste un peu compliqu\u00e9e \u00e0 lire qui contient pour chaque broche&nbsp;: son num\u00e9ro, son nom, le num\u00e9ro du mode s\u00e9lectionn\u00e9, la fonction s\u00e9lectionn\u00e9e et la liste des fonctions disponibles. Ci-dessous j&rsquo;ai align\u00e9 manuellement les colonnes pour am\u00e9liorer la lisibilit\u00e9.<\/p>\n<pre>[Panda]#<strong> \/root\/liste-j3.sh <\/strong>\n3  gpmc_ad7    1 sdmmc2_dat7 ( gpmc_ad7    sdmmc2_dat7 sdmmc2_clk_fdbk NA       NA  NA           NA  NA        )\n4  mcspi1_cs3  3 gpio_140    ( mcspi1_cs3  uart1_rts   slimbus2_data   gpio_140 NA  NA           NA  safe_mode )\n5  gpmc_ad6    1 sdmmc2_dat6 ( gpmc_ad6    sdmmc2_dat6 sdmmc2_dir_cmd  NA       NA  NA           NA  NA        )\n6  uart4_tx    0 uart4_tx    ( uart4_tx    sdmmc4_dat1 kpd_col8        gpio_156 NA  NA           NA  safe_mode )\n7  gpmc_ad5    1 sdmmc2_dat5 ( gpmc_ad5    sdmmc2_dat5 sdmmc2_dir_dat1 NA       NA  NA           NA  NA        )\n8  uart4_rx    0 uart4_rx    ( uart4_rx    sdmmc4_dat2 kpd_row8        gpio_155 NA  NA           NA  safe_mode )\n9  gpmc_ad4    1 sdmmc2_dat4 ( gpmc_ad4    sdmmc2_dat4 sdmmc2_dir_dat0 NA       NA  NA           NA  NA        )\n10 mcspi1_cs1  3 gpio_138    ( mcspi1_cs1  uart1_rx    NA              gpio_138 NA  NA           NA  safe_mode )\n11 gpmc_ad3    1 sdmmc2_dat3 ( gpmc_ad3    sdmmc2_dat3 NA              NA       NA  NA           NA  NA        )\n12 mcspi1_simo 0 mcspi1_simo ( mcspi1_simo NA          NA              gpio_136 NA  NA           NA  safe_mode )\n13 gpmc_ad2    1 sdmmc2_dat2 ( gpmc_ad2    sdmmc2_dat2 NA              NA       NA  NA           NA  NA        )\n14 mcspi1_cs2  3 gpio_139    ( mcspi1_cs2  uart1_cts   slimbus2_clock  gpio_139 NA  NA           NA  safe_mode )\n15 gpmc_ad1    1 sdmmc2_dat1 ( gpmc_ad1    sdmmc2_dat1 NA              NA       NA  NA           NA  NA        )\n16 mcspi1_cs0  0 mcspi1_cs0  ( mcspi1_cs0  NA          NA              gpio_137 NA  NA           NA  safe_mode )\n17 gpmc_ad0    1 sdmmc2_dat0 ( gpmc_ad0    sdmmc2_dat0 NA              NA       NA  NA           NA  NA        )\n18 mcspi1_somi 0 mcspi1_somi ( mcspi1_somi NA          NA              gpio_135 NA  NA           NA  safe_mode )\n19 gpmc_nwe    1 sdmmc2_cmd  ( gpmc_nwe    sdmmc2_cmd  NA              NA       NA  NA           NA  NA        )\n20 mcspi1_clk  0 mcspi1_clk  ( mcspi1_clk  NA          NA              gpio_134 NA  NA           NA  safe_mode )\n21 gpmc_noe    1 sdmmc2_clk  ( gpmc_noe    sdmmc2_clk  NA              NA       NA  NA           NA  NA        )\n22 gpmc_ad15   3 gpio_39     ( gpmc_ad15   kpd_col3    c2c_data8       gpio_39  NA  sdmmc1_dat7  NA  NA        )\n23 i2c4_sda    0 i2c4_sda    ( i2c4_sda    NA          NA              gpio_133 NA  NA           NA  safe_mode )\n24 i2c4_scl    0 i2c4_scl    ( i2c4_scl    NA  NA  gpio_132  NA  NA  NA  safe_mode)\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Prenons la ligne correspondant \u00e0 la broche num\u00e9ro 6 par exemple. Son nom est \u00ab\u00a0<code>uart4_tx<\/code>\u00a0\u00bb et il s&rsquo;agit \u00e9galement de sa fonction par d\u00e9faut car son mode initial est z\u00e9ro. Nous voyons dans la liste des fonctions possibles &#8211; entre parenth\u00e8ses &#8211; qu&rsquo;elle peut \u00eatre commut\u00e9e sur le GPIO 156 (mode 3). Nous allons essayer.<\/p>\n<p style=\"text-align: justify; padding-left: 60px;\">Petite parenth\u00e8se&nbsp;: une l\u00e9g\u00e8re erreur dans le script ci-dessus avait initialement d\u00e9cal\u00e9 les num\u00e9ros de broches et j&rsquo;ai pass\u00e9 un long moment \u00e0 essayer de chercher la fonction <code>uart4_tx<\/code> et le <code>gpio_156<\/code> sur la broche 7 au lieu de 6. Cette fois l&rsquo;erreur \u00e9tait inoffensive mais dans d&rsquo;autres circonstances un tel d\u00e9calage peut \u00eatre fatal au processeur (cela m&rsquo;est arriv\u00e9 r\u00e9cemment&#8230;) Soyez donc tr\u00e8s prudents dans les manipulations des GPIO de ce type de carte, les broches sont directement reli\u00e9es aux pattes du processeur sans plus de protection.<\/p>\n<p style=\"text-align: justify;\">Pour commencer, relions une sonde d&rsquo;oscilloscope \u00e0 la broche 6, et l&rsquo;autre \u00e0 la masse.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-34.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2351\" title=\"Broche 6 du connecteur J3\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-34.jpg\" alt=\"Broche 6 du connecteur J3\" width=\"600\" height=\"363\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Le signal est immobile, fix\u00e9 sur 1,8V. Nous allons demander au kernel d&rsquo;envoyer des donn\u00e9es sur la ligne s\u00e9rie <code>ttyO3<\/code>, ce qui se traduira par une activit\u00e9 sur la ligne d&rsquo;\u00e9mission (TX) de l&rsquo;UART num\u00e9ro 4.<\/p>\n<pre>[Panda]# <strong>cat \/bin\/ls &gt; \/dev\/ttyO3<\/strong><\/pre>\n<p style=\"text-align: justify;\">Alors que le noyau \u00e9met le contenu du fichier ex\u00e9cutable <code>\/bin\/ls<\/code> sur sa sortie s\u00e9rie, nous observons sur la broche 6 une activit\u00e9 incessante qui est typique d&rsquo;un transfert sur liaison s\u00e9rie.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-32.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2352\" title=\"UART4_TX sur broche 6\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-32.jpg\" alt=\"UART4_TX sur broche 6\" width=\"600\" height=\"436\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Apr\u00e8s avoir arret\u00e9 l&rsquo;\u00e9mission (avec <em>Contr\u00f4le-C<\/em>) nous basculons la broche 6 sur le GPIO 156 en modifiant le mode.<\/p>\n<pre>[Panda]# <strong>echo 0x0003 &gt; uart4_tx<\/strong>\n[Panda]#<\/pre>\n<p style=\"text-align: justify;\">Plus aucun signal n&rsquo;est visible sur l&rsquo;oscilloscope. Activons la sortie GPIO 156.<\/p>\n<pre>[Panda]# <strong>echo 156 &gt; \/sys\/class\/gpio\/export<\/strong>\n[Panda]# <strong>echo out &gt; \/sys\/class\/gpio\/gpio156\/direction<\/strong><\/pre>\n<p style=\"text-align: justify;\">Puis basculons r\u00e9gul\u00e8rement l&rsquo;\u00e9tat du GPIO 156 pour v\u00e9rifier si nous le voyons \u00e0 l&rsquo;oscilloscope.<\/p>\n<pre>[Panda]# <strong>while true; do echo 0 &gt; \/sys\/class\/gpio\/gpio156\/value ; usleep 100; echo 1 &gt; \/sys\/class\/gpio\/gpio156\/value; usleep 100; done<\/strong><\/pre>\n<p style=\"text-align: justify;\">Le signal carr\u00e9 est alors clairement visible.<\/p>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-33.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2353\" title=\"GPIO_156 sur brroche 6\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2012\/05\/img-33.jpg\" alt=\"GPIO_156 sur brroche 6\" width=\"600\" height=\"443\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Nous avons r\u00e9ussi \u00e0 basculer notre broche 6 du connecteur J3 de la fonction TX de l&rsquo;UART4 \u00e0 la fonction GPIO 156.<\/p>\n<h1>\u00a0Conclusion<\/h1>\n<p style=\"text-align: justify;\">Nous voyons que le pseudo syst\u00e8me de fichiers <code>debugfs<\/code> peut s&rsquo;av\u00e9rer tr\u00e8s utile pour consulter ou modifier les fonctions attribu\u00e9es aux broches de sortie du processeur OMAP. Il ne faut toutefois pas oublier que son interface est avant tout destin\u00e9e aux d\u00e9veloppeurs du kernel, aussi n&rsquo;y a-t-il aucune garantie de per\u00e9nit\u00e9 des param\u00e8tres configurables au gr\u00e9 des futures \u00e9volutions du noyau.<\/p>","protected":false},"excerpt":{"rendered":"<p>Suite &agrave; un petit commentaire de Yoann Sculo concernant l&rsquo;avant dernier article, j&rsquo;ai eu envie de d&eacute;tailler un peu le fonctionnement du multiplexage des GPIO sur un processeur OMAP (comme celui de la Pandaboard), et les param&egrave;tres auxquels nous pouvons avoir acc&egrave;s par l&rsquo;interm&eacute;diaire du syst&egrave;me de fichiers debugfs.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8,10,14],"tags":[],"class_list":["post-2301","post","type-post","status-publish","format-standard","hentry","category-embarque","category-linux-2","category-microprocesseur","category-temps-reel"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/2301","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=2301"}],"version-history":[{"count":0,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/2301\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=2301"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=2301"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=2301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}