Salut à tous.
Je sollicite vos compétences pour un problème auquel je m'attaque.
Voici le datasheet du broadcom 2835, celui de la raspberry pi 3B+.
Je désire manipuler les GPIO de la Raspberry Pi.
Autrement dit, je ne désire pas passer par les bibliothèques déjà existante mais le faire moi-même.
J'arrive à allumer et éteindre une led, ainsi que détecter la pression d'une bouton poussoir.
Mon problème n'est pas d'ordre électronique ais programmation système des GPIO de la Raspberry pi.
Pour les accès, je passe par "/dev/map". J'ai programmé cela dans ma fonction "GPIO_Start()".
Voici les fonctions que j'ai créés et que j'utilise déjà :
J'arrive à faire fonctionner les fonctions suivantes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 /************************************************************/ /* Bibliothèque de Gestion des GPIO avec "/Dev/Mem" */ /* */ /************************************************************/ #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <sys/mman.h> #include <bcm_host.h> #include "mygpio.h" /*************************************/ /* */ /* Déclaration des Variables */ /* */ /*************************************/ typedef unsigned int uint32_t; volatile uint32_t *_gpio; /*************************************/ /* */ /* Déclaration des Fonctions */ /* */ /*************************************/ void GPIO_Start(void) { unsigned int _base, _size; int _fd; void *_map; _base = bcm_host_get_peripheral_address() + 0x200000; _size = bcm_host_get_peripheral_size(); if ((_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { printf("Open '/dev/mem' Error\n"); exit(-1); } _map = mmap( NULL, _size, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, _base); close(_fd); if (_map == MAP_FAILED) { printf("Mmap Error : %8X\n", (int)_map); exit(-1); } _gpio = (volatile uint32_t*)_map; } void GPIO_In(unsigned short _pin) { *(_gpio + 0 + (_pin/10)) &= ~(7<<((_pin%10)*3)); } void GPIO_Out(unsigned short _pin) { *(_gpio + 0 + (_pin/10)) &= ~(7<<((_pin%10)*3)); *(_gpio + 0 + (_pin/10)) |= (1<<((_pin%10)*3)); } void GPIO_On(unsigned short _pin) { *(_gpio + 7 + (_pin/32)) = 1<<(_pin%32); } void GPIO_Off(unsigned short _pin) { *(_gpio + 10 + (_pin/32)) = 1<<(_pin%32); } unsigned char GPIO_Get(unsigned short _pin) { return ((*(_gpio + 13 + (_pin/32)) & (1<<(_pin%32)))?_HIGH_:_LOW_); } void GPIO_Put(unsigned short _pin, unsigned short _val) { if (_val > 0) GPIO_On(_pin); else GPIO_Off(_pin); } /*---------------------------------------------------------------*/ /* */ /*---------------------------------------------------------------*/ unsigned char GPIO_Event(unsigned short _pin) { return ((*(_gpio + 16 + (_pin/32)) & (1<<(_pin%32)))?_HIGH_:_LOW_); } void GPIO_Rising(unsigned short _pin) { *(_gpio + 19 + (_pin/32)) |= 1<<(_pin%32); } void GPIO_Falling(unsigned short _pin) { *(_gpio + 22 + (_pin/32)) |= 1<<(_pin%32); } void GPIO_High(unsigned short _pin) { *(_gpio + 25 + (_pin/32)) |= 1<<(_pin%32); } void GPIO_Low(unsigned short _pin) { *(_gpio + 28 + (_pin/32)) |= 1<<(_pin%32); } void GPIO_Finish(void) { unsigned short _pin; /*---------------------------------------*/ for (_pin=0; _pin<28; _pin++) GPIO_In(_pin); /* GPIO Function Select */ *(_gpio + 7) &= 0; *(_gpio + 8) &= 0; /* GPIO Pin Output Set */ *(_gpio + 10) &= 0; *(_gpio + 11) &= 0; /* GPIO Pin Output Clear */ *(_gpio + 16) &= 0; *(_gpio + 17) &= 0; /* GPIO Pin Event Detect Status */ *(_gpio + 19) &= 0; *(_gpio + 20) &= 0; /* GPIO Pin Rising Edge Detect Enable */ *(_gpio + 22) &= 0; *(_gpio + 23) &= 0; /* GPIO Pin Falling Edge Detect Enable */ *(_gpio + 25) &= 0; *(_gpio + 26) &= 0; /* GPIO Pin High Detect Enable */ *(_gpio + 28) &= 0; *(_gpio + 29) &= 0; /* GPIO Pin Low Detect Enable */ /*---------------------------------------*/ _gpio = MAP_FAILED; } void GPIO_Delay(unsigned int _elapse) { usleep(_elapse); }
--> GPIO_Start()
--> GPIO_In()
--> GPIO_Out()
--> GPIO_Off()
--> GPIO_On()
--> GPIO_Get()
--> GPIO_Put()
--> GPIO_Finish()
Par contre, j'ai des difficultés pour ce qui concerne les autres fonctions :
--> GPIO_Event()
--> GPIO_Rising()
--> GPIO_Falling()
--> GPIO_High()
--> GPIO_Low()
Mon but est le suivant.
Quand je manipule un bouton poussoir, j'ai deux mouvements qui sont détectés, à savoir la pression et le relâchement.
Cela se traduit par les termes "Rising" et "Falling".
Voir à ce sujet, la datasheet de la broadcom de la raspberry que j'ai donné ci-dessus.
D'après ce que j'ai compris, il faut positionner la GPIO dans la section "Rising" ou "Falling".
Je suppose l'un ou l'autre mais pas les deux (à confirmer).
Si le bouton poussoir est enfoncé et "Rising" est sélectionné alors un "Event" sera déclenché.
Si je relâche le bouton poussoir, il ne se passera rien, car je n'ai pas sélectionné "Falling".
Inversement, si je sélectionne "falling", "Event" se déclenche quand je relâche le bouton poussoir.
Tout ce que j'ai pu faire jusqu'à présent est de planter non pas le programme, par le système d'exploitation.
Je ne sais pas si mes six fonctions sont correctes.
Et j'aimerai savoir comment je dois faire pour manipuler ces fronts montants et descendants sans planter mon OS.
Merci.
Cordialement.
Artemus24.
@+
Partager