123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- MODULE Gpio; (** AUTHOR "Timothée Martiel"; PURPOSE "GPIO driver"; *)
- (*! TODO:
- - Interrupt configuration
- *)
- IMPORT Platform;
- CONST
- (** Direction: Input *)
- Input * = FALSE;
- (** Direction: Output *)
- Output * = TRUE;
- TYPE
- DataReg = POINTER {UNSAFE,UNTRACED} TO RECORD
- DATA: ARRAY 4 OF SET;
- DATA_RO: ARRAY 4 OF SET;
- END;
- BankCtrlReg = POINTER {UNSAFE,UNTRACED} TO RECORD
- DIRM, OEN, INT_MASK, INT_EN, INT_DIS, INT_STAT, INT_TYPE, INT_POLARITY, INT_ANY: SET;
- END;
- VAR
- bankCtrlRegs: ARRAY 4 OF BankCtrlReg;
- dataRegs: DataReg;
- i: LONGINT;
- (** Set the direction of 'gpio' to output if 'out' is TRUE and to input otherwise. *)
- PROCEDURE SetDirection * (gpio: LONGINT; out: BOOLEAN);
- VAR
- bank, ofs: LONGINT;
- BEGIN
- GetBankOfs(gpio, bank, ofs);
- IF (bank < 0) & (ofs < 0) THEN RETURN END;
- IF out THEN
- INCL(bankCtrlRegs[bank].DIRM, ofs)
- ELSE
- EXCL(bankCtrlRegs[bank].DIRM, ofs)
- END
- END SetDirection;
- (** If 'on' enable (if 'off' disable) output for 'gpio'. 'gpio' direction must be set to output prior to this call. *)
- PROCEDURE EnableOutput * (gpio: LONGINT; on: BOOLEAN);
- VAR
- bank, ofs: LONGINT;
- BEGIN
- GetBankOfs(gpio, bank, ofs);
- IF (bank < 0) & (ofs < 0) THEN RETURN END;
- IF on THEN
- INCL(bankCtrlRegs[bank].OEN, ofs)
- ELSE
- EXCL(bankCtrlRegs[bank].OEN, ofs)
- END
- END EnableOutput;
- (** Set the data of output GPIO 'gpio' to 'data' (TRUE for high, FALSE for low). *)
- PROCEDURE SetData * (gpio: LONGINT; data: BOOLEAN);
- VAR
- bank, ofs: LONGINT;
- BEGIN
- GetBankOfs(gpio, bank, ofs);
- IF (bank < 0) & (ofs < 0) THEN RETURN END;
- IF data THEN
- INCL(dataRegs.DATA[bank], ofs)
- ELSE
- EXCL(dataRegs.DATA[bank], ofs)
- END
- END SetData;
- (** Get data of input GPIO 'gpio': TRUE for high, FALSE for low. *)
- PROCEDURE GetData * (gpio: LONGINT): BOOLEAN;
- VAR
- bank, ofs: LONGINT;
- BEGIN
- GetBankOfs(gpio, bank, ofs);
- IF (bank < 0) & (ofs < 0) THEN HALT(100) END;
- RETURN ofs IN dataRegs.DATA_RO[bank]
- END GetData;
- PROCEDURE GetBankOfs (gpio: LONGINT; VAR bank, ofs: LONGINT);
- BEGIN
- IF gpio < 54 THEN
- bank := gpio DIV 32;
- ofs := gpio MOD 32
- ELSE
- (*! TODO: implement *)
- END;
- bank := -1;
- ofs := -1
- END GetBankOfs;
- BEGIN
- dataRegs := Platform.GpioData;
- FOR i := 0 TO Platform.GpioBankNb - 1 DO
- bankCtrlRegs[i] := Platform.GpioBank[i]
- END
- END Gpio.
|