ac91fdb79cf1cbaa3b9c0d90a42a33b34447cd64
[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 redef class Object
33 # This initialises wiringPi and assumes that the calling program is
34 # going to be using the wiringPi pin numbering scheme.
35 fun wiringPi_setup `{ wiringPiSetup(); `}
36 # Same as wiringPi_setup, however it allows the calling programs to
37 # use the Broadcom GPIO pin numbers directly with no re-mapping.
38 fun wiringPi_setup_gpio `{ wiringPiSetupGpio(); `}
39 # Identical to wiringPi_setup, however it allows the calling
40 # programs to use the physical pin numbers on the P1 connector only.
41 fun wiringPi_setup_phys `{ wiringPiSetupPhys(); `}
42 # This initialises wiringPi but uses the /sys/class/gpio interface
43 # rather than accessing the hardware directly.
44 fun wiringPi_setup_sys `{ wiringPiSetupSys(); `}
45 end
46
47 # A Raspberry Pi GPIO Pin
48 extern class RPiPin `{ CRPiPin *`}
49 new (id: Int) `{
50 CRPiPin *pin = malloc( sizeof(CRPiPin) );
51 pin->id = id;
52 return pin;
53 `}
54
55 # The pin `id` depends on wiringPi setup used
56 fun id: Int `{ return self->id; `}
57
58 # Sets the mode of the pin
59 fun mode(mode: RPiPinMode) `{ pinMode(self->id, mode); `}
60
61 # This sets the pull-up or pull-down resistor mode on the given pin,
62 # which should be set as an input.
63 fun pullup_dncontrol(pud: PUDControl) `{ pullUpDnControl(self->id, pud); `}
64
65 # Writes the value HIGH or LOW (true or false) to the given pin which must
66 # have been previously set as an output.
67 fun write(high: Bool) `{ digitalWrite(self->id, high? HIGH: LOW); `}
68
69 # Writes the value to the PWM register for the given pin.
70 # The Raspberry Pi has one on-board PWM pin, pin 1 (BMC_GPIO 18, Phys 12)
71 # and the range is 0-1024.
72 # Other PWM devices may have other PWM ranges.
73 fun pwm_write(value: Int) `{ pwmWrite(self->id, value); `}
74
75 # This function returns the value read at the given pin.
76 # It will be HIGH or LOW (true or false) depending on the logic level at the pin.
77 fun read: Bool `{ return digitalRead(self->id) == HIGH? true: false; `}
78 end
79
80 # RPI Pin modes
81 # Modes are:
82 # * INPUT
83 # * OUTPUT
84 # * PWM_OUTPUT
85 # * GPIO_CLOCK
86 # Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output
87 # and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.
88 extern class RPiPinMode `{ int `}
89 new input_mode `{ return INPUT; `}
90 new output_mode `{ return OUTPUT; `}
91 new pwm_mode `{ return PWM_OUTPUT; `}
92 new clock_mode `{ return GPIO_CLOCK; `}
93 end
94
95 # The BCM2835 has both pull-up an down internal resistors.
96 # The parameter pud should be:
97 # * PUD_OFF, (no pull up/down)
98 # * PUD_DOWN (pull to ground)
99 # * PUD_UP (pull to 3.3v)
100 # The internal pull up/down resistors have a value of approximately
101 # 50Kohms on the Raspberry Pi.
102 extern class PUDControl `{ int `}
103 new off `{ return PUD_OFF; `}
104 new down `{ return PUD_DOWN; `}
105 new up `{ return PUD_UP; `}
106 end
107
108 # Abstraction a daisy chain of 74×595 shift registers
109 class SR595
110 private var registers: Array[Bool]
111 private var nb_pins: Int
112 private var ser: RPiPin
113 private var rclk: RPiPin
114 private var srclk: RPiPin
115
116 # Initialize a new shift register chain
117 # `nb_pins`: number of pins available
118 # `ser_pin`: SER (serial) pin id
119 # `rclk_pin`: RCLK (register clock) pin id
120 # `srclk_pin`: SRCLK (serial clock) pin id
121 init(nb_pins, ser_pin, rclk_pin, srclk_pin: Int) do
122 # configure pin layout
123 self.nb_pins = nb_pins
124 self.ser = new RPiPin(7)
125 self.rclk = new RPiPin(6)
126 self.srclk = new RPiPin(5)
127 clear_registers
128 # enable output mode on shift register output
129 ser.mode(new RPiPinMode.output_mode)
130 rclk.mode(new RPiPinMode.output_mode)
131 srclk.mode(new RPiPinMode.output_mode)
132 end
133
134 # write 'state' on register 'reg'
135 fun write(reg: Int, state: Bool) do
136 registers[reg] = state
137 write_registers
138 end
139
140 # write all registers
141 fun write_all(regs: Array[Bool]) do
142 assert regs.length == nb_pins
143 registers = regs
144 write_registers
145 end
146
147 # clear all registers
148 fun clear_registers do
149 registers = new Array[Bool].filled_with(false, nb_pins)
150 write_registers
151 end
152
153 private fun write_registers do
154 rclk.write(false)
155 var i = registers.length - 1
156 while i >= 0 do
157 var reg = registers[i]
158 srclk.write(false)
159 ser.write(reg)
160 srclk.write(true)
161 i -= 1
162 end
163 rclk.write(true)
164 end
165 end
166