contrib/wiringPi: move pseudo-toplevel methods from Object
[nit.git] / contrib / wiringPi / lib / wiringPi.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2013 Alexandre Terrasa <alexandre@moz-code.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Nit wrapping of the wiringPi library [http://wiringpi.com/]
18 # WiringPi is an Arduino wiring-like library written in C
19 # and released under the GNU LGPLv3 license which is usable
20 # from C and C++ and many other languages with suitable wrappers
21 module wiringPi
22
23 in "C Header" `{
24 #include <wiringPi.h>
25
26 typedef struct {
27 int id;
28 } CRPiPin;
29 `}
30
31
32 # Initializes wiringPi.
33 # Assumes that the calling program is going to be using the wiringPi pin numbering scheme.
34 fun wiringPi_setup `{ wiringPiSetup(); `}
35
36 # Same as wiringPi_setup, but with GPIO.
37 # It allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping.
38 fun wiringPi_setup_gpio `{ wiringPiSetupGpio(); `}
39
40 # Same as to wiringPi_setup, but with physical pin numbers.
41 # It allows the calling programs to use the physical pin numbers on the P1 connector only.
42 fun wiringPi_setup_phys `{ wiringPiSetupPhys(); `}
43
44 # This initializes wiringPi, but with the /sys/class/gpio interface.
45 # Use `/sys/class/gpio` rather than accessing the hardware directly.
46 fun wiringPi_setup_sys `{ wiringPiSetupSys(); `}
47
48 # A Raspberry Pi GPIO Pin
49 extern class RPiPin `{ CRPiPin *`}
50 new (id: Int) `{
51 CRPiPin *pin = malloc( sizeof(CRPiPin) );
52 pin->id = id;
53 return pin;
54 `}
55
56 # The pin `id` depends on wiringPi setup used
57 fun id: Int `{ return self->id; `}
58
59 # Sets the mode of the pin
60 fun mode(mode: RPiPinMode) `{ pinMode(self->id, mode); `}
61
62 # This sets the pull-up or pull-down resistor mode on the given pin,
63 # which should be set as an input.
64 fun pullup_dncontrol(pud: PUDControl) `{ pullUpDnControl(self->id, pud); `}
65
66 # Writes the value HIGH or LOW (true or false) to the given pin which must
67 # have been previously set as an output.
68 fun write(high: Bool) `{ digitalWrite(self->id, high? HIGH: LOW); `}
69
70 # Writes the value to the PWM register for the given pin.
71 # The Raspberry Pi has one on-board PWM pin, pin 1 (BMC_GPIO 18, Phys 12)
72 # and the range is 0-1024.
73 # Other PWM devices may have other PWM ranges.
74 fun pwm_write(value: Int) `{ pwmWrite(self->id, value); `}
75
76 # This function returns the value read at the given pin.
77 # It will be HIGH or LOW (true or false) depending on the logic level at the pin.
78 fun read: Bool `{ return digitalRead(self->id) == HIGH? true: false; `}
79 end
80
81 # RPI Pin modes
82 # Modes are:
83 # * INPUT
84 # * OUTPUT
85 # * PWM_OUTPUT
86 # * GPIO_CLOCK
87 # Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output
88 # and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.
89 extern class RPiPinMode `{ int `}
90 new input_mode `{ return INPUT; `}
91 new output_mode `{ return OUTPUT; `}
92 new pwm_mode `{ return PWM_OUTPUT; `}
93 new clock_mode `{ return GPIO_CLOCK; `}
94 end
95
96 # The BCM2835 has both pull-up an down internal resistors.
97 # The parameter pud should be:
98 # * PUD_OFF, (no pull up/down)
99 # * PUD_DOWN (pull to ground)
100 # * PUD_UP (pull to 3.3v)
101 # The internal pull up/down resistors have a value of approximately
102 # 50Kohms on the Raspberry Pi.
103 extern class PUDControl `{ int `}
104 new off `{ return PUD_OFF; `}
105 new down `{ return PUD_DOWN; `}
106 new up `{ return PUD_UP; `}
107 end
108
109 # Abstraction a daisy chain of 74×595 shift registers
110 class SR595
111 private var registers: Array[Bool]
112 private var nb_pins: Int
113 private var ser: RPiPin
114 private var rclk: RPiPin
115 private var srclk: RPiPin
116
117 # Initialize a new shift register chain
118 # `nb_pins`: number of pins available
119 # `ser_pin`: SER (serial) pin id
120 # `rclk_pin`: RCLK (register clock) pin id
121 # `srclk_pin`: SRCLK (serial clock) pin id
122 init(nb_pins, ser_pin, rclk_pin, srclk_pin: Int) do
123 # configure pin layout
124 self.nb_pins = nb_pins
125 self.ser = new RPiPin(7)
126 self.rclk = new RPiPin(6)
127 self.srclk = new RPiPin(5)
128 clear_registers
129 # enable output mode on shift register output
130 ser.mode(new RPiPinMode.output_mode)
131 rclk.mode(new RPiPinMode.output_mode)
132 srclk.mode(new RPiPinMode.output_mode)
133 end
134
135 # write 'state' on register 'reg'
136 fun write(reg: Int, state: Bool) do
137 registers[reg] = state
138 write_registers
139 end
140
141 # write all registers
142 fun write_all(regs: Array[Bool]) do
143 assert regs.length == nb_pins
144 registers = regs
145 write_registers
146 end
147
148 # clear all registers
149 fun clear_registers do
150 registers = new Array[Bool].filled_with(false, nb_pins)
151 write_registers
152 end
153
154 private fun write_registers do
155 rclk.write(false)
156 var i = registers.length - 1
157 while i >= 0 do
158 var reg = registers[i]
159 srclk.write(false)
160 ser.write(reg)
161 srclk.write(true)
162 i -= 1
163 end
164 rclk.write(true)
165 end
166 end
167