• R/O
  • SSH
  • HTTPS

pasripherals: Commit


Commit MetaInfo

Revision32 (tree)
Time2019-09-15 06:13:22
Authorderekwildstar

Log Message

- Documentação atualizada
- Contém erros

Change Summary

Incremental Difference

--- trunk/src/lib/UPasRipherals.pas (revision 31)
+++ trunk/src/lib/UPasRipherals.pas (revision 32)
@@ -101,59 +101,68 @@
101101 //: funções que manipuluam os registradores GPFSEL. Existem seis registradores
102102 //: GPFSEL, numerados de 0 a 5, dentre os conjuntos de registradores de GPIO.
103103 //: @SeeAlso(TGPIOMode)
104- TPRGPIOModeBank = 0..5;
104+ TGPIOModeBank = 0..5;
105105 //: Esta enumeração representa os possíveis estados dos "resistores pull"
106106 //: associados a cada GPIO. Cada GPIO possui um "resitor pull" que serve para
107107 //: garantir um nível lógico inicial consistente quando o modo de operação de
108- //: um GPIO é @Link(prgmInput), ou seja, quando um GPIO está configurado para
108+ //: um GPIO é @Link(gmInput), ou seja, quando um GPIO está configurado para
109109 //: entrada de dados.
110110 //: @Value(prgprOff Desabilita qualquer resistor de pull para o GPIO. Se o
111111 //: GPIO não estiver sendo usado como entrada de dados, é seguro manter o
112112 //: resistor de pull desligado. O estado do GPIO quando um resistor pull não
113113 //: está sendo usado é chamado de floating (flutuante), porque a entrada de
114- //: dados fica alternando aleatoriamente entre @Link(prglLow) e
115- //: @Link(prglHigh) e é justamente por este motivo, que sempre se deve usar um
116- //: resistor pull quando o GPIO for usado como entrada de dados, pois queremos
117- //: saber com exatidão quando ele ficará em um nível lógico específico)
118- //: @Value(prgprDown Habilita o resistor "Pull Down", o qual força um nível
119- //: lógico zero (@Link(prglLow)) inicial. Usando esta configuração é garantido
120- //: que o valor lido do GPIO seja zero (@Link(prglLow)), até que, por algum
121- //: agente externo, ele se torne 1 (@Link(prglHigh)). Se você deseja detectar
122- //: uma mudança de estado lógico de @Link(prglLow) para @Link(prglHigh) em um
123- //: GPIO, o resistor pull deste GPIO precisa estar configurado como prgprDown.
114+ //: dados fica alternando aleatoriamente entre @Link(glLow) e @Link(glHigh) e
115+ //: é justamente por este motivo, que sempre se deve usar um resistor pull
116+ //: quando o GPIO for usado como entrada de dados, pois queremos saber com
117+ //: exatidão quando ele ficará em um nível lógico específico)
118+ //: @Value(gprDown Habilita o resistor "Pull Down", o qual força um nível
119+ //: lógico zero (@Link(glLow)) inicial. Usando esta configuração é garantido
120+ //: que o valor lido do GPIO seja zero (@Link(glLow)), até que, por algum
121+ //: agente externo, ele se torne 1 (@Link(glHigh)). Se você deseja detectar
122+ //: uma mudança de estado lógico de @Link(glLow) para @Link(glHigh) em um
123+ //: GPIO, o resistor pull deste GPIO precisa estar configurado como gprDown.
124124 //: O agente externo pode ser, por exemplo, um botão que, quando pressionado,
125125 //: conecta 3.3v ao GPIO, o qual, antes do pressionamento tinha nível lógico 0
126126 //: e após o pressionamento tem nível lógico 1)
127- //: @Value(prgprUp Habilita o resistor "Pull Up", o qual força um nível
128- //: lógico 1 (@Link(prglHigh)) inicial. Usando esta configuração é garantido
129- //: que o valor lido do GPIO seja 1 (@Link(prglHigh)), até que, por algum
130- //: agente externo, ele se torne 0 (@Link(prglLow)). Se você deseja detectar
131- //: uma mudança de estado lógico de @Link(prglHigh) para @Link(prglLow) em um
132- //: GPIO, o resistor pull deste GPIO precisa estar configurado como prgprUp. O
133- //: agente externo pode ser, por exemplo, um botão que, quando pressionado,
134- //: conecta GND ao GPIO, o qual, antes do pressionamento tinha nível lógico 1
135- //: e após o pressionamento tem nível lógico 0)
136- //: @SeeAlso(TPRGPIOLevel)
137- TPRGPIOPullRegister = (prgprOff,prgprDown,prgprUp);
138- //: Esta enumeração representa os dois possíveis níveis lógicos
139- //: @Value(prglLow Representa o nível lógico 0, e convenientemente tem valor
140- //: ordinal igual a zero dentro da enumeração)
141- //: @Value(prglHigh Representa o nível lógico 1, e convenientemente tem valor
142- //: ordinal igual a um dentro da enumeração)
143- TPRGPIOLevel = (prglLow,prglHigh);
127+ //: @Value(gprUp Habilita o resistor "Pull Up", o qual força um nível lógico 1
128+ //: (@Link(glHigh)) inicial. Usando esta configuração é garantido que o valor
129+ //: lido do GPIO seja 1 (@Link(glHigh)), até que, por algum agente externo,
130+ //: ele se torne 0 (@Link(glLow)). Se você deseja detectar uma mudança de
131+ //: estado lógico de @Link(glHigh) para @Link(glLow) em um GPIO, o resistor
132+ //: pull deste GPIO precisa estar configurado como prgprUp. O agente externo
133+ //: pode ser, por exemplo, um botão que, quando pressionado, conecta GND ao
134+ //: GPIO, o qual, antes do pressionamento tinha nível lógico 1 e após o
135+ //: pressionamento tem nível lógico 0)
136+ //: @SeeAlso(TGPIOLevel)
137+ TGPIOPullRegister = (gprOff,gprDown,gprUp);
138+ //: Esta enumeração representa os dois possíveis níveis lógicos que cada GPIO
139+ //: pode assumir
140+ //: @Value(glLow Representa o nível lógico 0, e convenientemente tem valor
141+ //: ordinal igual a @Code(0) dentro da enumeração)
142+ //: @Value(glHigh Representa o nível lógico 1, e convenientemente tem valor
143+ //: ordinal igual a @Code(1) dentro da enumeração)
144+ TGPIOLevel = (glLow,glHigh);
145+ //: Este tipo define um subconjunto numérico que representa um dos dois
146+ //: registradores de níveis lógicos dos GPIO (GPLEV0 e GPLEV1). Este tipo pode
147+ //: ser usado para explicitar que o número que form utilizado (@Code(0) ou @Code(1))
148+ //: representa um dos registradores de níveis lógicos
144149 TPRGPIOLevelBank = 0..1;
145150
146- { TPRGPIO }
151+ { TGPIO }
147152
148- {TODO: Tente revisar os métodos deste record pois eles parecem estar
149- demasiadamente complexos, verifique os records posteriores }
150-
151153 //: Este record representa um GPIO acessado a partir da classe TPasRipherals
152- //: @member(Mode Obtém ou configura o modo do GPIO)
153- //: @member(PullRegister Configura o resistor de pull do GPIO atual)
154- //: @member(ModeDescription Obtém a descrição textual do modo de operação do GPIO atual)
155- //: @member(Level Obtém ou configura o nível lógico do GPIO atual)
156- TPRGPIO = record
154+ //: @Member(Mode Obtém ou configura o modo do GPIO atual. @SeeAlso(TGPIOMode))
155+ //: @Member(PullRegister Configura o resistor de pull do GPIO atual. Não é
156+ //: possível ler a partir do RPI o estado dos resistores pull, por isso esta
157+ //: propriedade é somente de escrita. É responsabilidade do programador manter
158+ //: alguma variável que indique qual configuração de resistor de pull está
159+ //: sendo usada, pois o PasRipherals não realiza este controle.
160+ //: @SeeAlso(TGPIOPullRegister))
161+ //: @Member(ModeDescription Obtém a descrição textual do modo de operação do
162+ //: GPIO atual. @SeeAlso(TGPIOMode))
163+ //: @Member(Level Obtém ou configura o nível lógico do GPIO atual.
164+ //: @SeeAlso(TGPIOLevel))
165+ TGPIO = record
157166 private
158167 FGPIONumber: TGPIONumber;
159168 FPasRipherals: TCustomPasRipherals;
@@ -162,34 +171,45 @@
162171 // Funções acessórias para posicionamento de registradores e bits
163172 // -------------------------------------------------------------------------
164173
165- //: RegisterGroupIndex é responsável por selecionar um conjunto de
166- //: registradores de 32 bits no caso de haver mais de um conjunto desses
167- //: registradores por funcionalidade. Por exemplo, existem dois conjuntos de
168- //: registradores que contém os modos de cada GPIO, logo, RegisterGroupIndex
169- //: retorna um número de 0 a n-1, onde n é a quantidade de registradores, no
170- //: caso 2, logo, para este caso, RegisterGroupIndex retorna 0 ou 1. Fazer
171- //: FGPIONumber shr 5 é o mesmo que fazer FGPIONumber div 32, só que muito
172- //: mais rápido. Isso é uma propriedade que só funciona quando se divide um
173- //: número por uma potência de 2. 32 = 2^5, por isso se usa shr 5. Para mais
174- //: informações, leia: https://en.wikipedia.org/wiki/Division_by_two#Binary
175- function RegisterGroupIndex: UInt8;
176- //: RegisterBitIndex é responsvel por selecionar um dos bits dentro de um
177- //: registrador de 32 bits, portanto RegisterBitIndex retorna um valor de 0
178- //: a 31 sempre. FGPIONumber and 31 é o mesmo que fazer FGPIONumber mod 32,
179- //: só que muito mais rápido. Isso é uma propriedade que só se utiliza
180- //: quando se quer obter o módulo da divisão por um número que é potência de
181- //: 2. 31 = 2^5 - 1 <=> 32 - 1 = 31, por isso se use FGPIONumber and 31.
182- //: Para mais informações, leia: https://jacksondunstan.com/articles/1946
183- function RegisterBitIndex: UInt8;
184- //: RegisterBitValue é o valor que corresponde ao número binário formado
185- //: pelo bit ligado na posição indicada em RegisterBitIndex, por exemplo, se
186- //: FGPIONumber = 18, RegisterBitIndex = 18 e RegisterBitValue, em notação
174+ //: Esta função é responsável por selecionar um dos registradores, no caso
175+ //: de haver mais de um desses registradores por funcionalidade, quando a
176+ //: informação contida nestes é de exatamente 1 bit por GPIO, que em outras
177+ //: palavras faz com que o registrador tenha 32 campos (um para cada GPIO).
178+ //: Por exemplo, existem dois registradores que contém os níveis lógicos de
179+ //: cada GPIO, logo, esta função retorna um número de 0 a n-1, onde n é a
180+ //: quantidade de registradores que forma o conjunto, no caso 2, logo, para
181+ //: este caso, esta função retorna 0 ou 1.
182+ //:
183+ //: Esta função leva em conta que a informação referente ao GPIO dentro do
184+ //: registrador selecionado, ocupa apenas 1 bit deste. Isso é verdade para
185+ //: os registradores GPSET, GPCLR, GPLEV, GPED, GPREN, GPFEN, GPHEN, GPLEN,
186+ //: GPAREN, GPAFEN e GPPUDCLK. Em todos eles, cada um dos GPIO é
187+ //: representado por apenas um bit, pois a informação é apenas @Code(0) ou
188+ //: @Code(1) (@Code(False) ou @Code(True)). Este método, portanto, não pode
189+ //: ser usado para seleção de um dos registradores GPFSEL, pois nestes, cada
190+ //: GPIO precisa de 3 bits, logo, a função para obtenção do grupo correto a
191+ //: partir do número do GPIO é diferente
192+ //: @SeeAlso(_10FieldRegisterGroupIndex)
193+ function _32FieldRegisterGroupIndex: UInt8;
194+ //: Esta função é responsvel por selecionar um dos campos dentro de um
195+ //: registrador, quando cada campo tem exatamente um bit de tamanho. Como
196+ //: todos os registradores do RPI tem 32 bits, esta função retorna um valor
197+ //: de 0 a 31 sempre.
198+ function _1BitFieldIndex: UInt8;
199+ //: Esta função retorna o valor que corresponde ao número binário formado
200+ //: pelo bit ligado na posição indicada em _1BitFieldIndex, por exemplo, se
201+ //: FGPIONumber = 18, _1BitFieldIndex = 18 e _1BitFieldValue, em notação
187202 //: binária, é um 1, seguido de 18 zeros, que corresponde a 262.144 decimal.
188- //: Seria possível usar FPasRipherals.GetBitsValue, contudo, todos os usos
189- //: de RegisterBitValue dentro de TPRGPIO são bem específicos a fim de tornar
190- //: as coias mais rápidas, enquanto FPasRipherals.GetBitsValue é levemente
191- //: mais lenta por ser uma função mais genérica
192- function RegisterBitValue: UInt32;
203+ function _1BitFieldValue: UInt32;
204+ //: Esta função é responsável por selecionar um dos registradores, no caso
205+ //: de haver mais de um desses registradores por funcionalidade, quando a
206+ //: informação contida nestes é de exatamente 3 bits por GPIO, que em outras
207+ //: palavras faz com que o registrador tenha 10 campos (um para cada GPIO).
208+ //: Por exemplo, existem seis registradores que contém os modos de operação
209+ //: de cada GPIO, logo, esta função retorna um número de 0 a n-1, onde n é a
210+ //: quantidade de registradores que forma o conjunto, no caso 6, logo, para
211+ //: este caso, esta função retorna um valor comprendido entre 0 e 5.
212+ function _10FieldRegisterGroupIndex: UInt8;
193213
194214 // -------------------------------------------------------------------------
195215 // As funções RegisterGP* contém offsets de registradores acessíveis. Cada
@@ -201,68 +221,111 @@
201221 // próximo conjunto, incremente-o com RegisterGroupIndex
202222 // -------------------------------------------------------------------------
203223
204- //: RegisterGPFSEL retorna um ponteiro para um dos registradores GPFSEL. A
205- //: seleção do registrador correto se dá por meio de FGPIONumber div 10
224+ //: Esta função retorna um ponteiro para um dos registradores GPFSEL. A
225+ //: seleção do registrador correto é automática e depende do número do GPIO
226+ //: atual
206227 function RegisterGPFSEL: PUInt32;
207- //: RegisterGPLEV retorna um ponteiro para um dos registradores GPLEV. A
208- //: seleção do registrador correto se dá por meio de RegisterGroupIndex
228+ //: Esta função retorna um ponteiro para um dos registradores GPLEV. A
229+ //: seleção do registrador correto é automática e depende do número do GPIO
230+ //: atual
209231 function RegisterGPLEV: PUInt32;
210- //: RegisterGPSET retorna um ponteiro para um dos registradores GPSET. A
211- //: seleção do registrador correto se dá por meio de RegisterGroupIndex
232+ //: Esta função retorna um ponteiro para um dos registradores GPSET. A
233+ //: seleção do registrador correto é automática e depende do número do GPIO
234+ //: atual
212235 function RegisterGPSET: PUInt32;
213- //: RegisterGPCLR retorna um ponteiro para um dos registradores GPCLR. A
214- //: seleção do registrador correto se dá por meio de RegisterGroupIndex
236+ //: Esta função retorna um ponteiro para um dos registradores GPCLR. A
237+ //: seleção do registrador correto é automática e depende do número do GPIO
238+ //: atual
215239 function RegisterGPCLR: PUInt32;
216- //: RegisterGPPUD retorna um ponteiro para o registrador GPPUD
240+ //: Esta função retorna um ponteiro para o registrador GPPUD
217241 function RegisterGPPUD: PUInt32;
218- //: RegisterGPPUDCLK retorna um ponteiro para um dos registradores GPPUDCLK.
219- //: A seleção do registrador correto se dá por meio de RegisterGroupIndex.
242+ //: Esta função retorna um ponteiro para um dos registradores GPPUDCLK. A
243+ //: seleção do registrador correto é automática e depende do número do GPIO
244+ //: atual
220245 function RegisterGPPUDCLK: PUInt32;
221246
222247 function GetModeDescription: String;
223- function GetLevel: TPRGPIOLevel;
248+ function GetLevel: TGPIOLevel;
224249 function GetMode: TGPIOMode;
225- procedure SetLevel(AGPIOLevel: TPRGPIOLevel);
250+ procedure SetLevel(AGPIOLevel: TGPIOLevel);
226251 procedure SetMode(AGPIOMode: TGPIOMode);
227- procedure SetPullRegister(AGPIOPullRegister: TPRGPIOPullRegister);
252+ procedure SetPullRegister(AGPIOPullRegister: TGPIOPullRegister);
228253 public
229254 property Mode: TGPIOMode read GetMode write SetMode;
230- property PullRegister: TPRGPIOPullRegister write SetPullRegister;
255+ property PullRegister: TGPIOPullRegister write SetPullRegister;
231256 property ModeDescription: String read GetModeDescription;
232- property Level: TPRGPIOLevel read GetLevel write SetLevel;
257+ property Level: TGPIOLevel read GetLevel write SetLevel;
233258 end;
234259
235- TPRPWMChannel = 0..1;
236- TPRPWMPolarity = (prppNormal,prppInverted);
260+ //: Este tipo define um subconjunto numérico para representar um dos dois
261+ //: canais PWM existentes no RPI
262+ TPWMChannel = 0..1;
263+ //: Esta enumeração define os dois possíveis valores para a polaridade de cada
264+ //: canal PWM (Campos POLA1 e POLA2 do registrador CTL. DataSheet p. 141-143)
265+ //: @Value(ppNormal Polaridade normal (padrão))
266+ //: @Value(ppInverted Polaridade invertida)
267+ TPWMPolarity = (ppNormal,ppInverted);
237268
238- { TPRPWM }
269+ { TPWM }
239270
240- TPRPWM = record
271+ //: Este record representa um caal PWM acessado a partir da classe
272+ //: TPasRipherals
273+ //: @Member(MarkSpaceEnabled Habilita ou desabilita o modo Mark/Space no canal
274+ //: PWM atual. Quando o modo Mark/Space está desabilitado o canal usa o modo
275+ //: PWM normal. (Campos MSEN1 e MSEN2 do registrador CTL. DataSheet p. 141-143)
276+ //: @Member(Enabled Habilita ou desabilita o canal PWM atual (Campos PWMEN2 e
277+ //: PWMEN2 do registrador CTL. DataSheet p. 141-143))
278+ //: @Member(Polarity Alterna a polaridade do canal PWM atual (Campos POLA1 e
279+ //: POLA2 do registrador CTL. DataSheet p. 141-143))
280+ //: @Member(Range Define ou obtém o range (intervalo) de funcionamento do
281+ //: canal PWM atual (Registradores RNG1 e RNG2. DataSheet p. 145 e 146))
282+ //: @Member(Data Define ou obtém o valor de configuração do canal PWM atual
283+ //: (Registradores DAT1 e DAT2. DataSheet p. 146 e 147))
284+ //: @Member(CurrentConfig Obtém de forma textual todas as configurações do
285+ //: canal PWM atual)
286+ TPWM = record
241287 private
242- FPWMChannel: TPRPWMChannel;
288+ FPWMChannel: TPWMChannel;
243289 FPasRipherals: TCustomPasRipherals;
244290
291+ //: Esta função retorna um ponteiro para o registrador CTL
245292 function RegisterCTL: PUInt32;
293+ //: Esta função retorna um ponteiro para o registrador RNG
246294 function RegisterRNG: PUInt32;
295+ //: Esta função retorna um ponteiro para o registrador DAT
247296 function RegisterDAT: PUInt32;
248297
249298 function GetCurrentConfig: String;
250299 function GetData: UInt32;
251300 function GetEnabled: Boolean;
252- function GetPolarity: TPRPWMPolarity;
301+ function GetPolarity: TPWMPolarity;
253302 function GetMarkSpaceEnabled: Boolean;
254303 function GetRange: UInt32;
255304 procedure SetData(APWMData: UInt32);
256305 procedure SetEnabled(APWMEnabled: Boolean);
257- procedure SetPolarity(APWMPolarity: TPRPWMPolarity);
306+ procedure SetPolarity(APWMPolarity: TPWMPolarity);
258307 procedure SetMarkSpaceEnabled(APWMMarkSpaceEnabled: Boolean);
259308 procedure SetRange(APWMRange: UInt32);
260309 public
261310 //: Configura todas as características do PWM atual de uma só vez e de forma
262- //: livre
263- procedure Configure(AMarkSpaceEnabled: Boolean; APolarity: TPRPWMPolarity; ARange: UInt32; AData: UInt32; AEnabled: Boolean); overload;
311+ //: livre. É recomendável usar a outra versão desta função, mais
312+ //: simplificada e direcionada para parâmetros da vida real, como datasheets
313+ //: de servos
314+ //: @Param(AMarkSpaceEnabled Habilita o modo Mark/Space (true) ou mantém o
315+ //: modo PWM tradicional (false) no canal PWM atual)
316+ //: @Param(APolarity Define a polaridade a ser usada pelo canal PWM atual,
317+ //: @Link(ppNormal) para polaridade normal ou @Link(ppInverted) para
318+ //: polaridade invertida)
319+ //: @Param(ARange Define o range a ser utilizado pelo canal PWM atual)
320+ //: @Param(AData Define o valor, dentro do range, a ser usado pelo canal PWM
321+ //: atual)
322+ //: @Param(AEnabled Ao final da execução do procedure, caso AEnabled seja
323+ //: true, o canal PWM atual será automaticamente habilitado, caso seja false
324+ //: ele se manterá desabilitado)
325+ //: @SeeAlso(TPWMPolarity)
326+ procedure Configure(AMarkSpaceEnabled: Boolean; APolarity: TPWMPolarity; ARange: UInt32; AData: UInt32; AEnabled: Boolean); overload;
264327 //: Configura de forma simplificada o PWM. Esta função configura o modo
265- //: Mark-Space, define a polaridade como @Link(prppNormal), calcula o range
328+ //: Mark-Space, define a polaridade como @Link(ppNormal), calcula o range
266329 //: de acordo com o ciclo de repetição informado, configura o registrador
267330 //: DAT na posição mediana de acordo com os valores de ADutyCycleMin e
268331 //: ADutyCycleMax e, opcionalmente, habilita o PWM.
@@ -298,7 +361,7 @@
298361
299362 property MarkSpaceEnabled: Boolean read GetMarkSpaceEnabled write SetMarkSpaceEnabled;
300363 property Enabled: Boolean read GetEnabled write SetEnabled;
301- property Polarity: TPRPWMPolarity read GetPolarity write SetPolarity;
364+ property Polarity: TPWMPolarity read GetPolarity write SetPolarity;
302365 property Range: UInt32 read GetRange write SetRange;
303366 property Data: UInt32 read GetData write SetData;
304367 property CurrentConfig: String read GetCurrentConfig;
@@ -306,15 +369,44 @@
306369
307370 { Para criar um novo record de periférico, inclua de forma privada um ou mais
308371 campos para o seletor (no caso de haver mais de um periférico do mesmo tipo) e
309- um campo privado para acesso a TPasRipherals. As propriedades expostas serão
310- sempre relativas a elementos internos dos registradores aplicáveis, por
372+ um campo privado para acesso a TCustomPasRipherals. As propriedades expostas
373+ serão sempre relativas a elementos internos dos registradores aplicáveis, por
311374 exemplo, se um dos registradores do periférico define que determinados bits
312375 correspondem a um modo de operação, haverá uma propriedade "modo" que vai
313376 atuar (ler e/ou escrever) apenas naqueles bits específicos. Crie funções para
314- acesso direto a cada um dos registradores do periférico. }
377+ acesso direto a cada um dos registradores do periférico. Use outros records
378+ como exemplo }
315379
316- TPRClockId = (prciGP0, prciGP1, prciGP2, prciPCM, prciPWM);
317- TPRClockSource = (prcsGND, prcsOscillator, prcsTestDebug0, prcsTestDebug1, prcsPLLA, prcsPLLC, prcsPLLD, prcsHDMIAuxiliary, prcsGND8, prcsGND9, prcsGND10, prcsGND11, prcsGND12, prcsGND13, prcsGND14, prcsGND15);
380+ //: Esta enumeração representa os possíveis clocks que o RPI possui
381+ //: @Value(ciGP0 Use este valor para referir-se ao clock geral 0)
382+ //: @Value(ciGP1 Use este valor para referir-se ao clock geral 1)
383+ //: @Value(ciGP2 Use este valor para referir-se ao clock geral 2)
384+ //: @Value(ciPCM Use este valor para referir-se ao clock de PCM)
385+ //: @Value(ciPWM Use este valor para referir-se ao clock de PWM)
386+ TClockId = (ciGP0, ciGP1, ciGP2, ciPCM, ciPWM);
387+ //: Esta enumeração representa todas as possíveis fontes de geração de pulsos
388+ //: de clock disponíveis no RPI
389+ //: @Value(csGND Não existe gerador de pulso de clock para este valor)
390+ //: @Value(csOscillator Refere-se ao oscilador interno como gerador de pulsos
391+ //: de clock)
392+ //: @Value(csTestDebug0)
393+ //: @Value(csTestDebug1)
394+ defina aqui o resto das explicações para os geradores de clock. coloque suas frequencias
395+ //: @Value(csPLLA)
396+ //: @Value(csPLLC)
397+ //: @Value(csPLLD)
398+ //: @Value(csHDMIAuxiliary)
399+
400+
401+ //: @Value(csGND8 Não existe gerador de pulso de clock para este valor)
402+ //: @Value(csGND9 Não existe gerador de pulso de clock para este valor)
403+ //: @Value(csGND10 Não existe gerador de pulso de clock para este valor)
404+ //: @Value(csGND11 Não existe gerador de pulso de clock para este valor)
405+ //: @Value(csGND12 Não existe gerador de pulso de clock para este valor)
406+ //: @Value(csGND13 Não existe gerador de pulso de clock para este valor)
407+ //: @Value(csGND14 Não existe gerador de pulso de clock para este valor)
408+ //: @Value(csGND15 Não existe gerador de pulso de clock para este valor)
409+ TClockSource = (csGND, csOscillator, csTestDebug0, csTestDebug1, csPLLA, csPLLC, csPLLD, csHDMIAuxiliary, csGND8, csGND9, csGND10, csGND11, csGND12, csGND13, csGND14, csGND15);
318410 //: Este tipo enumerado define os tipos de "mash" de clocks disponíveis
319411 //: @value(prcmInteger Este valor indica que está sendo usado um divisor
320412 //: inteiro)
@@ -332,13 +424,13 @@
332424
333425 TPRClock = record
334426 private
335- FClockId: TPRClockId;
427+ FClockId: TClockId;
336428 FPasRipherals: TCustomPasRipherals;
337429
338430 function RegisterCTL: PUInt32;
339431 function RegisterDIV: PUInt32;
340432
341- function GetSource: TPRClockSource;
433+ function GetSource: TClockSource;
342434 function GetSourceHertz: UInt32;
343435 function GetEnabled: Boolean;
344436 function GetMash: TPRClockMash;
@@ -345,13 +437,13 @@
345437 function GetDivI: TPRClockDivI;
346438 function GetDivF: TPRClockDivF;
347439 function GetDivisor: Double;
348- procedure SetSource(ASource: TPRClockSource);
440+ procedure SetSource(ASource: TClockSource);
349441 procedure SetEnabled(AEnabled: Boolean);
350442 procedure SetMash(AMash: TPRClockMash);
351443 procedure SetDivI(ADivI: TPRClockDivI);
352444 procedure SetDivF(ADivF: TPRClockDivF);
353445 public
354- property Source: TPRClockSource read GetSource write SetSource;
446+ property Source: TClockSource read GetSource write SetSource;
355447 property SourceHertz: UInt32 read GetSourceHertz;
356448 property Enabled: Boolean read GetEnabled write SetEnabled;
357449 property Mash: TPRClockMash read GetMash write SetMash;
@@ -364,7 +456,7 @@
364456 //: suficientemente grande para garantir o funcionamento adequado.
365457 //: Normalmente usar um divisor inteiro e igual a 2 é suficiente. Diminua o
366458 //: clock apenas se for necessário
367- procedure Configure(ASource: TPRClockSource; AMash: TPRClockMash; ADivI: TPRClockDivI; ADivF: TPRClockDivF; AEnabled: Boolean);
459+ procedure Configure(ASource: TClockSource; AMash: TPRClockMash; ADivI: TPRClockDivI; ADivF: TPRClockDivF; AEnabled: Boolean);
368460 end;
369461
370462 //: Existem 3 controladores BSC principais: BSC0, BSC1 e BSC2. O BSC2 é usado
@@ -735,18 +827,18 @@
735827 FPeripherals: PUInt32;
736828 FRunningAsRoot: Boolean;
737829
738- function GetClock(AClockId: TPRClockId): TPRClock;
739- function GetGPIO(AGPIONumber: TGPIONumber): TPRGPIO;
740- function GetPWM(APWMChannel: TPRPWMChannel): TPRPWM;
830+ function GetClock(AClockId: TClockId): TPRClock;
831+ function GetGPIO(AGPIONumber: TGPIONumber): TGPIO;
832+ function GetPWM(APWMChannel: TPWMChannel): TPWM;
741833 function GetI2C(AController: TPRI2CController; ASlaveAddress: TPRI2CSlaveAddress): TPRI2C;
742834
743835 function GetLevels(ALevelBank: TPRGPIOLevelBank): UInt32;
744- function GetModes(AModeBank: TPRGPIOModeBank): UInt32;
836+ function GetModes(AModeBank: TGPIOModeBank): UInt32;
745837 function GetState: TSavedState;
746838 function GetInfo: String;
747839
748840 procedure SetLevels(ALevelBank: TPRGPIOLevelBank; ALevels: UInt32);
749- procedure SetModes(AModeBank: TPRGPIOModeBank; AModes: UInt32);
841+ procedure SetModes(AModeBank: TGPIOModeBank; AModes: UInt32);
750842 procedure SetState(ASavedState: TSavedState);
751843
752844 function ClockBaseAddress: PUInt32;
@@ -770,12 +862,12 @@
770862 //: um registrador de até 32 bits de tamanho
771863 procedure SetBitsValue(ARegister: PUInt32; AValue: UInt32; ABitIndex: UInt8; ABitsCount: UInt8 = 1);
772864
773- property Clock[AClockId: TPRClockId]: TPRClock read GetClock;
774- property GPIO[AGPIONumber: TGPIONumber]: TPRGPIO read GetGPIO;
775- property PWM[APWMChannel: TPRPWMChannel]: TPRPWM read GetPWM;
865+ property Clock[AClockId: TClockId]: TPRClock read GetClock;
866+ property GPIO[AGPIONumber: TGPIONumber]: TGPIO read GetGPIO;
867+ property PWM[APWMChannel: TPWMChannel]: TPWM read GetPWM;
776868 property I2C[AController: TPRI2CController; ASlaveAddress: TPRI2CSlaveAddress]: TPRI2C read GetI2C;
777869 property GPIOLevels[ALevelBank: TPRGPIOLevelBank]: UInt32 read GetLevels write SetLevels;
778- property GPIOModes[AModeBank: TPRGPIOModeBank]: UInt32 read GetModes write SetModes;
870+ property GPIOModes[AModeBank: TGPIOModeBank]: UInt32 read GetModes write SetModes;
779871 property State: TSavedState read GetState write SetState;
780872 property Info: String read GetInfo;
781873 public
@@ -1354,11 +1446,11 @@
13541446 begin
13551447 // Seleciona o registrador correto de acordo com o ID do clock
13561448 case FClockId of
1357- prciGP0: Result := FPasRipherals.ClockBaseAddress + GP0CLOCK_CTL;
1358- prciGP1: Result := FPasRipherals.ClockBaseAddress + GP1CLOCK_CTL;
1359- prciGP2: Result := FPasRipherals.ClockBaseAddress + GP2CLOCK_CTL;
1360- prciPCM: Result := FPasRipherals.ClockBaseAddress + PCMCLOCK_CTL;
1361- prciPWM: Result := FPasRipherals.ClockBaseAddress + PWMCLOCK_CTL;
1449+ ciGP0: Result := FPasRipherals.ClockBaseAddress + GP0CLOCK_CTL;
1450+ ciGP1: Result := FPasRipherals.ClockBaseAddress + GP1CLOCK_CTL;
1451+ ciGP2: Result := FPasRipherals.ClockBaseAddress + GP2CLOCK_CTL;
1452+ ciPCM: Result := FPasRipherals.ClockBaseAddress + PCMCLOCK_CTL;
1453+ ciPWM: Result := FPasRipherals.ClockBaseAddress + PWMCLOCK_CTL;
13621454 end;
13631455 end;
13641456
@@ -1366,18 +1458,18 @@
13661458 begin
13671459 // Seleciona o registrador correto de acordo com o ID do clock
13681460 case FClockId of
1369- prciGP0: Result := FPasRipherals.ClockBaseAddress + GP0CLOCK_DIV;
1370- prciGP1: Result := FPasRipherals.ClockBaseAddress + GP1CLOCK_DIV;
1371- prciGP2: Result := FPasRipherals.ClockBaseAddress + GP2CLOCK_DIV;
1372- prciPCM: Result := FPasRipherals.ClockBaseAddress + PCMCLOCK_DIV;
1373- prciPWM: Result := FPasRipherals.ClockBaseAddress + PWMCLOCK_DIV;
1461+ ciGP0: Result := FPasRipherals.ClockBaseAddress + GP0CLOCK_DIV;
1462+ ciGP1: Result := FPasRipherals.ClockBaseAddress + GP1CLOCK_DIV;
1463+ ciGP2: Result := FPasRipherals.ClockBaseAddress + GP2CLOCK_DIV;
1464+ ciPCM: Result := FPasRipherals.ClockBaseAddress + PCMCLOCK_DIV;
1465+ ciPWM: Result := FPasRipherals.ClockBaseAddress + PWMCLOCK_DIV;
13741466 end;
13751467 end;
13761468
1377-function TPRClock.GetSource: TPRClockSource;
1469+function TPRClock.GetSource: TClockSource;
13781470 begin
13791471 // Bits de 0 a 3 do registrador CTL
1380- Result := TPRClockSource(FPasRipherals.GetBitsValue(RegisterCTL^,CLOCK_CTL_SRC,CLOCK_CTL_SRC_SIZE));
1472+ Result := TClockSource(FPasRipherals.GetBitsValue(RegisterCTL^,CLOCK_CTL_SRC,CLOCK_CTL_SRC_SIZE));
13811473 end;
13821474
13831475 function TPRClock.GetSourceHertz: UInt32;
@@ -1385,10 +1477,10 @@
13851477 Result := 0;
13861478
13871479 case GetSource of
1388- prcsOscillator: Result := 19200000; // 19.2 MHz
1389- prcsPLLC: Result := 1000000000; // 1 GHz (1000 MHz) (Esse valor muda quando se aplica um overclock)
1390- prcsPLLD: Result := 500000000; // 500 MHz
1391- prcsHDMIAuxiliary: Result := 216000000 // 216MHz
1480+ csOscillator: Result := 19200000; // 19.2 MHz
1481+ csPLLC: Result := 1000000000; // 1 GHz (1000 MHz) (Esse valor muda quando se aplica um overclock)
1482+ csPLLD: Result := 500000000; // 500 MHz
1483+ csHDMIAuxiliary: Result := 216000000 // 216MHz
13921484 end;
13931485 end;
13941486
@@ -1426,7 +1518,7 @@
14261518 Result := GetDivI + GetDivF / 1024;
14271519 end;
14281520
1429-procedure TPRClock.SetSource(ASource: TPRClockSource);
1521+procedure TPRClock.SetSource(ASource: TClockSource);
14301522 begin
14311523 Configure(ASource,GetMash,GetDivI,GetDivF,GetEnabled);
14321524 end;
@@ -1451,7 +1543,7 @@
14511543 Configure(GetSource,GetMash,GetDivI,ADivF,GetEnabled);
14521544 end;
14531545
1454-procedure TPRClock.Configure(ASource: TPRClockSource; AMash: TPRClockMash; ADivI: TPRClockDivI; ADivF: TPRClockDivF; AEnabled: Boolean);
1546+procedure TPRClock.Configure(ASource: TClockSource; AMash: TPRClockMash; ADivI: TPRClockDivI; ADivF: TPRClockDivF; AEnabled: Boolean);
14551547 var
14561548 PWMCTLRegister: UInt32;
14571549 begin
@@ -1506,7 +1598,7 @@
15061598 // temporariamente o PWM, do contrário o sinalizador BUSY nunca vai desligar
15071599 // (segundo o WiringPi). A fim de tornar isso possível, precisamos guardar
15081600 // todo o registrador CTL do PWM, para posteriormente recuperá-lo
1509- if FClockId = prciPWM then
1601+ if FClockId = ciPWM then
15101602 PWMCTLRegister := (FPasRipherals.PWMBaseAddress + PWM_CTL)^;
15111603
15121604 try
@@ -1514,7 +1606,7 @@
15141606 // zerar completamente todo o registrador CTL do PWM, contudo, todos os
15151607 // dados serão recuperados no final deste método. Fazer isso é mais
15161608 // eficiente do que zerar apenas os bits PWEN1 e PWEN2
1517- if FClockId = prciPWM then
1609+ if FClockId = ciPWM then
15181610 (FPasRipherals.PWMBaseAddress + PWM_CTL)^ := 0;
15191611
15201612 // Para o clock (datasheet p. 107). Atribuir apenas PASSWORD, implica que
@@ -1559,7 +1651,7 @@
15591651 finally
15601652 // Recupera o registrador CTL do PWM, caso o clock atual seja um clock de
15611653 // PWM
1562- if FClockId = prciPWM then
1654+ if FClockId = ciPWM then
15631655 (FPasRipherals.PWMBaseAddress + PWM_CTL)^ := PWMCTLRegister;
15641656 end;
15651657
@@ -1577,14 +1669,14 @@
15771669 // errou ;)
15781670 end;
15791671
1580-{ TPRPWM }
1672+{ TPWM }
15811673
1582-function TPRPWM.RegisterCTL: PUInt32;
1674+function TPWM.RegisterCTL: PUInt32;
15831675 begin
15841676 Result := FPasRipherals.PWMBaseAddress + PWM_CTL;
15851677 end;
15861678
1587-function TPRPWM.RegisterDAT: PUInt32;
1679+function TPWM.RegisterDAT: PUInt32;
15881680 begin
15891681 case FPWMChannel of
15901682 0: Result := FPasRipherals.PWMBaseAddress + PWM_DAT1;
@@ -1592,7 +1684,7 @@
15921684 end;
15931685 end;
15941686
1595-function TPRPWM.RegisterRNG: PUInt32;
1687+function TPWM.RegisterRNG: PUInt32;
15961688 begin
15971689 case FPWMChannel of
15981690 0: Result := FPasRipherals.PWMBaseAddress + PWM_RNG1;
@@ -1600,13 +1692,13 @@
16001692 end;
16011693 end;
16021694
1603-function TPRPWM.GetCurrentConfig: String;
1695+function TPWM.GetCurrentConfig: String;
16041696 const
16051697 OUTPUT = '<pwm%u><pwen>%s</pwen><pola>%s</pola><msen>%s</msen><rng>%u</rng><dat>%u</dat></pwm%0:u>';
16061698 begin
16071699 Result := Format(OUTPUT,[FPWMChannel
16081700 ,BoolToStr(GetEnabled,True)
1609- ,IfThen(GetPolarity = prppNormal,'Normal','Inverted')
1701+ ,IfThen(GetPolarity = ppNormal,'Normal','Inverted')
16101702 ,BoolToStr(GetMarkSpaceEnabled,True)
16111703 ,GetRange
16121704 ,GetData
@@ -1613,60 +1705,60 @@
16131705 ]);
16141706 end;
16151707
1616-function TPRPWM.GetData: UInt32;
1708+function TPWM.GetData: UInt32;
16171709 begin
16181710 Result := RegisterDAT^;
16191711 end;
16201712
1621-function TPRPWM.GetEnabled: Boolean;
1713+function TPWM.GetEnabled: Boolean;
16221714 begin
16231715 Result := FPasRipherals.GetBitsValue(RegisterCTL^,PWM_CTL_PWEN + (8 * FPWMChannel),PWM_CTL_PWEN_SIZE).ToBoolean;
16241716 end;
16251717
1626-function TPRPWM.GetMarkSpaceEnabled: Boolean;
1718+function TPWM.GetMarkSpaceEnabled: Boolean;
16271719 begin
16281720 Result := FPasRipherals.GetBitsValue(RegisterCTL^,PWM_CTL_MSEN + (8 * FPWMChannel),PWM_CTL_MSEN_SIZE).ToBoolean;
16291721 end;
16301722
1631-function TPRPWM.GetPolarity: TPRPWMPolarity;
1723+function TPWM.GetPolarity: TPWMPolarity;
16321724 begin
1633- Result := TPRPWMPolarity(FPasRipherals.GetBitsValue(RegisterCTL^,PWM_CTL_POLA + (8 * FPWMChannel),PWM_CTL_POLA_SIZE));
1725+ Result := TPWMPolarity(FPasRipherals.GetBitsValue(RegisterCTL^,PWM_CTL_POLA + (8 * FPWMChannel),PWM_CTL_POLA_SIZE));
16341726 end;
16351727
1636-function TPRPWM.GetRange: UInt32;
1728+function TPWM.GetRange: UInt32;
16371729 begin
16381730 Result := RegisterRNG^;
16391731 end;
16401732
1641-procedure TPRPWM.SetData(APWMData: UInt32);
1733+procedure TPWM.SetData(APWMData: UInt32);
16421734 begin
16431735 RegisterDAT^ := APWMData;
16441736 end;
16451737
1646-procedure TPRPWM.SetEnabled(APWMEnabled: Boolean);
1738+procedure TPWM.SetEnabled(APWMEnabled: Boolean);
16471739 begin
16481740 Configure(GetMarkSpaceEnabled,GetPolarity,GetRange,GetData,APWMEnabled);
16491741 // FPasRipherals.SetBitsValue(RegisterCTL,APWMEnabled.ToInteger,PWM_CTL_PWEN + (8 * FPWMChannel),PWM_CTL_PWEN_SIZE);
16501742 end;
16511743
1652-procedure TPRPWM.SetMarkSpaceEnabled(APWMMarkSpaceEnabled: Boolean);
1744+procedure TPWM.SetMarkSpaceEnabled(APWMMarkSpaceEnabled: Boolean);
16531745 begin
16541746 Configure(APWMMarkSpaceEnabled,GetPolarity,GetRange,GetData,GetEnabled);
16551747 // FPasRipherals.SetBitsValue(RegisterCTL,APWMMarkSpaceEnabled.ToInteger,PWM_CTL_MSEN + (8 * FPWMChannel),1);
16561748 end;
16571749
1658-procedure TPRPWM.SetPolarity(APWMPolarity: TPRPWMPolarity);
1750+procedure TPWM.SetPolarity(APWMPolarity: TPWMPolarity);
16591751 begin
16601752 Configure(GetMarkSpaceEnabled,APWMPolarity,GetRange,GetData,GetEnabled);
16611753 // FPasRipherals.SetBitsValue(RegisterCTL,Byte(APWMPolarity),PWM_CTL_POLA + (8 * FPWMChannel),PWM_CTL_POLA_SIZE);
16621754 end;
16631755
1664-procedure TPRPWM.SetRange(APWMRange: UInt32);
1756+procedure TPWM.SetRange(APWMRange: UInt32);
16651757 begin
16661758 RegisterRNG^ := APWMRange;
16671759 end;
16681760
1669-procedure TPRPWM.Configure(AMarkSpaceEnabled: Boolean; APolarity: TPRPWMPolarity; ARange: UInt32; AData: UInt32; AEnabled: Boolean);
1761+procedure TPWM.Configure(AMarkSpaceEnabled: Boolean; APolarity: TPWMPolarity; ARange: UInt32; AData: UInt32; AEnabled: Boolean);
16701762 var
16711763 Mask: UInt32;
16721764 Configurations: UInt32;
@@ -1677,7 +1769,7 @@
16771769 // um range ou data errados. Ao depurar, tenha isso em mente. Recomendo não
16781770 // depurar este método ou colocar o breakpoint no fim dele, a fim de que todas
16791771 // as instruções ocorram o mais rápido possível, sem que se configure, por
1680- // exemplo, um range, enquanto o data está inadequado. Aviso dado!
1772+ // exemplo, um range, enquanto o data está inadequado. AVISO DADO!
16811773 RegisterRNG^ := ARange;
16821774 RegisterDAT^ := AData;
16831775
@@ -1702,7 +1794,7 @@
17021794 RegisterCTL^ := RegisterCTL^ and not Mask or Configurations;
17031795 end;
17041796
1705-procedure TPRPWM.Configure(ARepeatCycle: UInt16; ADutyCycleMin: UInt32; ADutyCycleMax: UInt32; AEnabled: Boolean);
1797+procedure TPWM.Configure(ARepeatCycle: UInt16; ADutyCycleMin: UInt32; ADutyCycleMax: UInt32; AEnabled: Boolean);
17061798 var
17071799 RangeValue: UInt32;
17081800 DataValue: UInt32;
@@ -1716,7 +1808,7 @@
17161808 // "PWM Repeat Cycle" é o ciclo de repetição do PWM, também conhecido como
17171809 // período e normalmente apresentado no datasheet em hertz. "PWM Clock
17181810 // Divisor" é o divisor de clock utilizado
1719- RangeValue := FPasRipherals.Clock[prciPWM].SourceHertz div Round(FPasRipherals.Clock[prciPWM].Divisor) div ARepeatCycle;
1811+ RangeValue := FPasRipherals.Clock[ciPWM].SourceHertz div Round(FPasRipherals.Clock[ciPWM].Divisor) div ARepeatCycle;
17201812 SetRange(RangeValue);
17211813
17221814 // Obtém o período em microssegundos
@@ -1728,12 +1820,12 @@
17281820
17291821 // Executa o procedure Configure a fim de configurar o restante das
17301822 // propriedades
1731- Configure(True,prppNormal,RangeValue,DataValue,AEnabled);
1823+ Configure(True,ppNormal,RangeValue,DataValue,AEnabled);
17321824 end;
17331825
1734-{ TPRGPIO }
1826+{ TGPIO }
17351827
1736-function TPRGPIO.GetMode: TGPIOMode;
1828+function TGPIO.GetMode: TGPIOMode;
17371829 var
17381830 Shift: UInt8;
17391831 begin
@@ -1746,45 +1838,67 @@
17461838 Shift := (FGPIONumber mod 10) * 3;
17471839
17481840 case (RegisterGPFSEL^ shr Shift) and 7 of
1749- 0: Result := prgmInput;
1750- 1: Result := prgmOutput;
1751- 2: Result := prgmAlt5;
1752- 3: Result := prgmAlt4;
1753- 4: Result := prgmAlt0;
1754- 5: Result := prgmAlt1;
1755- 6: Result := prgmAlt2;
1756- 7: Result := prgmAlt3;
1841+ 0: Result := gmInput;
1842+ 1: Result := gmOutput;
1843+ 2: Result := gmAlt5;
1844+ 3: Result := gmAlt4;
1845+ 4: Result := gmAlt0;
1846+ 5: Result := gmAlt1;
1847+ 6: Result := gmAlt2;
1848+ 7: Result := gmAlt3;
17571849 end;
17581850 end;
17591851
1760-procedure TPRGPIO.SetLevel(AGPIOLevel: TPRGPIOLevel);
1852+procedure TGPIO.SetLevel(AGPIOLevel: TGPIOLevel);
17611853 begin
1762- if GetMode = prgmOutput then
1854+ if GetMode = gmOutput then
17631855 begin
1764- if AGPIOLevel = prglLow then
1765- RegisterGPCLR^ := RegisterBitValue
1856+ if AGPIOLevel = glLow then
1857+ RegisterGPCLR^ := _1BitFieldValue
17661858 else
1767- RegisterGPSET^ := RegisterBitValue;
1859+ RegisterGPSET^ := _1BitFieldValue;
17681860 end;
17691861 end;
17701862
1771-function TPRGPIO.RegisterGroupIndex: UInt8;
1863+function TGPIO._32FieldRegisterGroupIndex: UInt8;
17721864 begin
1865+ // Fazer FGPIONumber shr 5 é o mesmo que fazer FGPIONumber div 32, só que
1866+ // muito mais rápido. Isso é uma propriedade que só funciona quando se divide
1867+ // um número por uma potência de 2. 32 = 2^5, por isso se usa shr 5. Para mais
1868+ // informações, leia: https://en.wikipedia.org/wiki/Division_by_two#Binary
17731869 Result := FGPIONumber shr 5;
17741870 end;
17751871
1776-function TPRGPIO.RegisterBitIndex: UInt8;
1872+function TGPIO._1BitFieldIndex: UInt8;
17771873 begin
1874+ // FGPIONumber and 31 é o mesmo que fazer FGPIONumber mod 32, só que muito
1875+ // mais rápido. Isso é uma propriedade que só se utiliza quando se quer obter
1876+ // o módulo da divisão por um número que é potência de 2. 31 = 2^5 - 1 <=> 32
1877+ // - 1 = 31, por isso se use FGPIONumber and 31. Para mais informações, leia:
1878+ // https://jacksondunstan.com/articles/1946
17781879 Result := FGPIONumber and 31;
17791880 end;
17801881
1781-function TPRGPIO.RegisterBitValue: UInt32;
1882+function TGPIO._1BitFieldValue: UInt32;
17821883 begin
1783- Result := 1 shl RegisterBitIndex;
1884+ // Seria possível usar TPasRipherals.GetBitsValue, contudo, todos os usos
1885+ // da função atual dentro de TGPIO são bem específicos a fim de tornar as
1886+ // coisas mais rápidas, enquanto TPasRipherals.GetBitsValue é levemente mais
1887+ // lenta por ser uma função mais genérica
1888+ Result := 1 shl _1BitFieldIndex;
17841889 end;
17851890
1786-function TPRGPIO.RegisterGPFSEL: PUInt32;
1891+function TGPIO._10FieldRegisterGroupIndex: UInt8;
17871892 begin
1893+ // Ao realizar a divisão inteira por 10 estamos garantindo que para um dado
1894+ // FGPIONumber o valor retornado fique compreendido entre 0 e 5 para qualquer
1895+ // um dos 54 GPIOs disponíveis, selecionando assim um registrador correto
1896+ // dentre vários existentes em um grupo
1897+ Result := FGPIONumber div 10;
1898+end;
1899+
1900+function TGPIO.RegisterGPFSEL: PUInt32;
1901+begin
17881902 // Cada um dos 6 registradores GPIO_GPFSEL comporta um máximo de 10 pinos.
17891903 // Fazendo a divisão inteira por 10, estamos selecionando um dos seis
17901904 // registradores disponíves. De 0 a 9, A função retorna 0, logo, GFPSEL0. De
@@ -1792,40 +1906,44 @@
17921906 // dos registradores tem 32 bits e FPasRipherals.GPIOBaseAddress é um PUInt32,
17931907 // logo, valores somados a ele, incrementam o ponteiro automaticamente em 32
17941908 // bits. FPasRipherals.GPIOBaseAddress + 1, significa que estamos no segundo
1795- // UInt32, ou seja, no segundo registrador que é GFPSEL1, por exemplo
1796- Result := FPasRipherals.GPIOBaseAddress + GPIO_GPFSEL + FGPIONumber div 10;
1909+ // UInt32, ou seja, no segundo registrador que é GFPSEL1, por exemplo. Note
1910+ // que esta função é muito semelhante as demais funções "Register*", as
1911+ // diferenças são os offsets somados diretamente FPasRipherals.GPIOBaseAddress
1912+ // e o seletor de registrador, que aqui utiliza _10FieldRegisterGroupIndex
1913+ // enquantos as demais utilizam _32FieldRegisterGroupIndex
1914+ Result := FPasRipherals.GPIOBaseAddress + GPIO_GPFSEL + _10FieldRegisterGroupIndex;
17971915 end;
17981916
1799-function TPRGPIO.RegisterGPLEV: PUInt32;
1917+function TGPIO.RegisterGPLEV: PUInt32;
18001918 begin
18011919 // Acessa o registrador correto somando FPasRipherals.GPIOBaseAddress +
1802- // GPIO_GPLEV + RegisterGroupIndex.
1803- Result := FPasRipherals.GPIOBaseAddress + GPIO_GPLEV + RegisterGroupIndex;
1920+ // GPIO_GPLEV + _32FieldRegisterGroupIndex.
1921+ Result := FPasRipherals.GPIOBaseAddress + GPIO_GPLEV + _32FieldRegisterGroupIndex;
18041922 end;
18051923
1806-function TPRGPIO.RegisterGPSET: PUInt32;
1924+function TGPIO.RegisterGPSET: PUInt32;
18071925 begin
1808- Result := FPasRipherals.GPIOBaseAddress + GPIO_GPSET + RegisterGroupIndex;
1926+ Result := FPasRipherals.GPIOBaseAddress + GPIO_GPSET + _32FieldRegisterGroupIndex;
18091927 end;
18101928
1811-function TPRGPIO.RegisterGPCLR: PUInt32;
1929+function TGPIO.RegisterGPCLR: PUInt32;
18121930 begin
1813- Result := FPasRipherals.GPIOBaseAddress + GPIO_GPCLR + RegisterGroupIndex;
1931+ Result := FPasRipherals.GPIOBaseAddress + GPIO_GPCLR + _32FieldRegisterGroupIndex;
18141932 end;
18151933
1816-function TPRGPIO.RegisterGPPUD: PUInt32;
1934+function TGPIO.RegisterGPPUD: PUInt32;
18171935 begin
18181936 Result := FPasRipherals.GPIOBaseAddress + GPIO_GPPUD;
18191937 end;
18201938
1821-function TPRGPIO.RegisterGPPUDCLK: PUInt32;
1939+function TGPIO.RegisterGPPUDCLK: PUInt32;
18221940 begin
1823- Result := FPasRipherals.GPIOBaseAddress + GPIO_GPPUDCLK + RegisterGroupIndex;
1941+ Result := FPasRipherals.GPIOBaseAddress + GPIO_GPPUDCLK + _32FieldRegisterGroupIndex;
18241942 end;
18251943
1826-function TPRGPIO.GetModeDescription: String;
1944+function TGPIO.GetModeDescription: String;
18271945 const
1828- ALTERNATETIVE_FUNCTION_NAMES: array [TPRGPIOModeBank] of array [TGPIONumber] of String =
1946+ ALTERNATETIVE_FUNCTION_NAMES: array [TGPIOModeBank] of array [TGPIONumber] of String =
18291947 // ALT0
18301948 (('I2C SDA0','I2C SCL0','I2C SDA1','I2C SCL1','GPCLK0','GPCLK1','GPCLK2','SPI0 CE1/'
18311949 ,'SPI0 CE0/','SPI0 MISO','SPI0 MOSI','SPI0 SCLK','PWM0','PWM1','TxD0','RxD0'
@@ -1868,30 +1986,30 @@
18681986 ,'','','','','','','','','',''));
18691987 begin
18701988 case GetMode of
1871- prgmInput: Result := 'DIGITAL INPUT';
1872- prgmOutput: Result := 'DIGITAL OUTPUT';
1873- prgmAlt0: Result := ALTERNATETIVE_FUNCTION_NAMES[0][FGPIONumber];
1874- prgmAlt1: Result := ALTERNATETIVE_FUNCTION_NAMES[1][FGPIONumber];
1875- prgmAlt2: Result := ALTERNATETIVE_FUNCTION_NAMES[2][FGPIONumber];
1876- prgmAlt3: Result := ALTERNATETIVE_FUNCTION_NAMES[3][FGPIONumber];
1877- prgmAlt4: Result := ALTERNATETIVE_FUNCTION_NAMES[4][FGPIONumber];
1878- prgmAlt5: Result := ALTERNATETIVE_FUNCTION_NAMES[5][FGPIONumber];
1989+ gmInput: Result := 'DIGITAL INPUT';
1990+ gmOutput: Result := 'DIGITAL OUTPUT';
1991+ gmAlt0: Result := ALTERNATETIVE_FUNCTION_NAMES[0][FGPIONumber];
1992+ gmAlt1: Result := ALTERNATETIVE_FUNCTION_NAMES[1][FGPIONumber];
1993+ gmAlt2: Result := ALTERNATETIVE_FUNCTION_NAMES[2][FGPIONumber];
1994+ gmAlt3: Result := ALTERNATETIVE_FUNCTION_NAMES[3][FGPIONumber];
1995+ gmAlt4: Result := ALTERNATETIVE_FUNCTION_NAMES[4][FGPIONumber];
1996+ gmAlt5: Result := ALTERNATETIVE_FUNCTION_NAMES[5][FGPIONumber];
18791997 end;
18801998 end;
18811999
1882-function TPRGPIO.GetLevel: TPRGPIOLevel;
2000+function TGPIO.GetLevel: TGPIOLevel;
18832001 begin
1884- // Um valor é obtido fazendo um and entre RegisterGPLEV^ e RegisterBitValue,
2002+ // Um valor é obtido fazendo um and entre RegisterGPLEV^ e _1BitFieldValue,
18852003 // portanto este valor pode ser zero ou o número correspondente ao bit ligado
1886- // na posição indicada em RegisterBitIndex. Como a intenção aqui é retornar 0
1887- // ou 1, a fim de aproveitar o cast com TPRGPIOLevel, ao final o valor é
1888- // movimentado para a direita RegisterBitIndex bits e isso faz com que os
2004+ // na posição indicada em _1BitFieldIndex. Como a intenção aqui é retornar 0
2005+ // ou 1, a fim de aproveitar o cast com TGPIOLevel, ao final o valor é
2006+ // movimentado para a direita _1BitFieldIndex bits e isso faz com que os
18892007 // valores retornados sejam sempre 0 ou 1, permitindo o cast direto!
1890- if GetMode in [prgmInput,prgmOutput] then
1891- Result := TPRGPIOLevel((RegisterGPLEV^ and RegisterBitValue) shr RegisterBitIndex);
2008+ if GetMode in [gmInput,gmOutput] then
2009+ Result := TGPIOLevel((RegisterGPLEV^ and _1BitFieldValue) shr _1BitFieldIndex);
18922010 end;
18932011
1894-procedure TPRGPIO.SetMode(AGPIOMode: TGPIOMode);
2012+procedure TGPIO.SetMode(AGPIOMode: TGPIOMode);
18952013 var
18962014 Shift: UInt8;
18972015 begin
@@ -1901,7 +2019,7 @@
19012019 or (Byte(AGPIOMode) shl Shift); // Altera os 3 bits do grupo, transformando apenas eles no valor especificado
19022020 end;
19032021
1904-procedure TPRGPIO.SetPullRegister(AGPIOPullRegister: TPRGPIOPullRegister);
2022+procedure TGPIO.SetPullRegister(AGPIOPullRegister: TGPIOPullRegister);
19052023 begin
19062024 // Atribui ao registrador o valor que se quer configurar, atualmente apenas 3
19072025 // valores são aceitos, 0 (off), 1 (down) e 2 (up). Um desperdício de espaço,
@@ -1914,12 +2032,12 @@
19142032 // 1us, tempo mais que suficiente
19152033 FPasRipherals.MicroSleep(1);
19162034
1917- // RegisterBitValue é o número binário formado por um 1 seguido vários zeros,
2035+ // _1BitFieldValue é o número binário formado por um 1 seguido vários zeros,
19182036 // de forma que o 1, fique na posição exata correspondente ao GPIO que se quer
19192037 // manipular. Atribui-se o valor completo resultante ao registrador, porque o
19202038 // estado dos resistores de pull não pode ser lido, só escrito, por isso não é
19212039 // necessário se preocupar com o estado de outros bits
1922- RegisterGPPUDCLK^ := RegisterBitValue;
2040+ RegisterGPPUDCLK^ := _1BitFieldValue;
19232041
19242042 // Aguarda 1us novamente
19252043 FPasRipherals.MicroSleep(1);
@@ -1931,7 +2049,7 @@
19312049
19322050 { TCustomPasRipherals }
19332051
1934-function TCustomPasRipherals.GetClock(AClockId: TPRClockId): TPRClock;
2052+function TCustomPasRipherals.GetClock(AClockId: TClockId): TPRClock;
19352053 begin
19362054 if not FRunningAsRoot then
19372055 raise EPasRipherals.Create('Não é possível acessar o CLOCK porque você não tem privilégios suficientes');
@@ -1940,7 +2058,7 @@
19402058 Result.FClockId := AClockId;
19412059 end;
19422060
1943-function TCustomPasRipherals.GetGPIO(AGPIONumber: TGPIONumber): TPRGPIO;
2061+function TCustomPasRipherals.GetGPIO(AGPIONumber: TGPIONumber): TGPIO;
19442062 begin
19452063 Result.FPasRipherals := Self;
19462064 Result.FGPIONumber := AGPIONumber;
@@ -1951,7 +2069,7 @@
19512069 Result := (GPIOBaseAddress + GPIO_GPLEV + Byte(ALevelBank))^;
19522070 end;
19532071
1954-function TCustomPasRipherals.GetModes(AModeBank: TPRGPIOModeBank): UInt32;
2072+function TCustomPasRipherals.GetModes(AModeBank: TGPIOModeBank): UInt32;
19552073 begin
19562074 Result := (GPIOBaseAddress + GPIO_GPFSEL + Byte(AModeBank))^;
19572075 end;
@@ -2056,7 +2174,7 @@
20562174 // ADataMax := ADesiredRange * ADutyCycleMax div UInt32(APeriod * 1000);
20572175 //end;
20582176
2059-function TCustomPasRipherals.GetPWM(APWMChannel: TPRPWMChannel): TPRPWM;
2177+function TCustomPasRipherals.GetPWM(APWMChannel: TPWMChannel): TPWM;
20602178 begin
20612179 if not FRunningAsRoot then
20622180 raise EPasRipherals.Create('Não é possível acessar o PWM porque você não tem privilégios suficientes');
@@ -2086,7 +2204,7 @@
20862204 (GPIOBaseAddress + GPIO_GPCLR + Byte(ALevelBank))^ := not ALevels;
20872205 end;
20882206
2089-procedure TCustomPasRipherals.SetModes(AModeBank: TPRGPIOModeBank; AModes: UInt32);
2207+procedure TCustomPasRipherals.SetModes(AModeBank: TGPIOModeBank; AModes: UInt32);
20902208 begin
20912209 (GPIOBaseAddress + GPIO_GPSET + Byte(AModeBank))^ := AModes;
20922210 end;
@@ -2300,14 +2418,14 @@
23002418 for G := Low(TGPIONumber) to High(TGPIONumber) do
23012419 begin
23022420 case GPIO[G].Mode of
2303- prgmAlt0: M := 'ALT0';
2304- prgmAlt1: M := 'ALT1';
2305- prgmAlt2: M := 'ALT2';
2306- prgmAlt3: M := 'ALT3';
2307- prgmAlt4: M := 'ALT4';
2308- prgmAlt5: M := 'ALT5';
2309- prgmInput: M := 'INPUT';
2310- prgmOutput: M := 'OUTPUT';
2421+ gmAlt0: M := 'ALT0';
2422+ gmAlt1: M := 'ALT1';
2423+ gmAlt2: M := 'ALT2';
2424+ gmAlt3: M := 'ALT3';
2425+ gmAlt4: M := 'ALT4';
2426+ gmAlt5: M := 'ALT5';
2427+ gmInput: M := 'INPUT';
2428+ gmOutput: M := 'OUTPUT';
23112429 end;
23122430
23132431 if G = 28 then
@@ -2314,9 +2432,9 @@
23142432 Result += '╟─────────────╫─────────────────────╫────────╫────────────────╫─────────────╢'#13#10;
23152433
23162434 if G > 27 then
2317- Result += Format(INFOLINE,[G,'--- UNAVAILABLE ---',M,GPIO[G].ModeDescription,IfThen(GPIO[G].Level = prglLow,'LOW','HIGH')]) + #13#10
2435+ Result += Format(INFOLINE,[G,'--- UNAVAILABLE ---',M,GPIO[G].ModeDescription,IfThen(GPIO[G].Level = glLow,'LOW','HIGH')]) + #13#10
23182436 else
2319- Result += Format(INFOLINE,[G,Format('%u',[G2P(G)]),M,GPIO[G].ModeDescription,IfThen(GPIO[G].Level = prglLow,'LOW','HIGH')]) + #13#10
2437+ Result += Format(INFOLINE,[G,Format('%u',[G2P(G)]),M,GPIO[G].ModeDescription,IfThen(GPIO[G].Level = glLow,'LOW','HIGH')]) + #13#10
23202438 end;
23212439
23222440 Result += '╚═════════════╩═════════════════════╩════════╩════════════════╩═════════════╝'#13#10;
@@ -2326,7 +2444,7 @@
23262444 const
23272445 INFOLINE = '║ %-7u ║ %-6s ║ %-10s ║ %-8s ║ %-14u ║ %-13u ║';
23282446 var
2329- P: TPRPWMChannel;
2447+ P: TPWMChannel;
23302448 A: UInt32;
23312449 S: UInt32;
23322450 begin
@@ -2341,12 +2459,12 @@
23412459 Result += '╠═════════╬════════╬════════════╬══════════╬════════════════╬═══════════════╣'#13#10;
23422460
23432461
2344- for P := Low(TPRPWMChannel) to High(TPRPWMChannel) do
2462+ for P := Low(TPWMChannel) to High(TPWMChannel) do
23452463 begin
23462464 Result += Format(INFOLINE,[P
23472465 ,IfThen(PWM[P].Enabled,'YES','NO')
23482466 ,IfThen(PWM[P].MarkSpaceEnabled,'ENABLED','DISABLED')
2349- ,IfThen(PWM[P].Polarity = prppNormal,'NORMAL','INVERTED')
2467+ ,IfThen(PWM[P].Polarity = ppNormal,'NORMAL','INVERTED')
23502468 ,PWM[P].Range
23512469 ,PWM[P].Data]) + #13#10
23522470 end;
Show on old repository browser