# This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2013 Alexandre Terrasa # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Nit wrapping of the wiringPi library [http://wiringpi.com/] # WiringPi is an Arduino wiring-like library written in C # and released under the GNU LGPLv3 license which is usable # from C and C++ and many other languages with suitable wrappers module wiringPi in "C Header" `{ #include typedef struct { int id; } CRPiPin; `} # Initializes wiringPi. # Assumes that the calling program is going to be using the wiringPi pin numbering scheme. fun wiringPi_setup `{ wiringPiSetup(); `} # Same as wiringPi_setup, but with GPIO. # It allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping. fun wiringPi_setup_gpio `{ wiringPiSetupGpio(); `} # Same as to wiringPi_setup, but with physical pin numbers. # It allows the calling programs to use the physical pin numbers on the P1 connector only. fun wiringPi_setup_phys `{ wiringPiSetupPhys(); `} # This initializes wiringPi, but with the /sys/class/gpio interface. # Use `/sys/class/gpio` rather than accessing the hardware directly. fun wiringPi_setup_sys `{ wiringPiSetupSys(); `} # A Raspberry Pi GPIO Pin extern class RPiPin `{ CRPiPin *`} new (id: Int) `{ CRPiPin *pin = malloc( sizeof(CRPiPin) ); pin->id = id; return pin; `} # The pin `id` depends on wiringPi setup used fun id: Int `{ return self->id; `} # Sets the mode of the pin fun mode(mode: RPiPinMode) `{ pinMode(self->id, mode); `} # This sets the pull-up or pull-down resistor mode on the given pin, # which should be set as an input. fun pullup_dncontrol(pud: PUDControl) `{ pullUpDnControl(self->id, pud); `} # Writes the value HIGH or LOW (true or false) to the given pin which must # have been previously set as an output. fun write(high: Bool) `{ digitalWrite(self->id, high? HIGH: LOW); `} # Writes the value to the PWM register for the given pin. # The Raspberry Pi has one on-board PWM pin, pin 1 (BMC_GPIO 18, Phys 12) # and the range is 0-1024. # Other PWM devices may have other PWM ranges. fun pwm_write(value: Int) `{ pwmWrite(self->id, value); `} # This function returns the value read at the given pin. # It will be HIGH or LOW (true or false) depending on the logic level at the pin. fun read: Bool `{ return digitalRead(self->id) == HIGH? true: false; `} end # RPI Pin modes # Modes are: # * INPUT # * OUTPUT # * PWM_OUTPUT # * GPIO_CLOCK # Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output # and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. extern class RPiPinMode `{ int `} new input_mode `{ return INPUT; `} new output_mode `{ return OUTPUT; `} new pwm_mode `{ return PWM_OUTPUT; `} new clock_mode `{ return GPIO_CLOCK; `} end # The BCM2835 has both pull-up an down internal resistors. # The parameter pud should be: # * PUD_OFF, (no pull up/down) # * PUD_DOWN (pull to ground) # * PUD_UP (pull to 3.3v) # The internal pull up/down resistors have a value of approximately # 50Kohms on the Raspberry Pi. extern class PUDControl `{ int `} new off `{ return PUD_OFF; `} new down `{ return PUD_DOWN; `} new up `{ return PUD_UP; `} end # Abstraction a daisy chain of 74×595 shift registers class SR595 private var registers: Array[Bool] private var nb_pins: Int private var ser: RPiPin private var rclk: RPiPin private var srclk: RPiPin # Initialize a new shift register chain # `nb_pins`: number of pins available # `ser_pin`: SER (serial) pin id # `rclk_pin`: RCLK (register clock) pin id # `srclk_pin`: SRCLK (serial clock) pin id init(nb_pins, ser_pin, rclk_pin, srclk_pin: Int) do # configure pin layout self.nb_pins = nb_pins self.ser = new RPiPin(7) self.rclk = new RPiPin(6) self.srclk = new RPiPin(5) clear_registers # enable output mode on shift register output ser.mode(new RPiPinMode.output_mode) rclk.mode(new RPiPinMode.output_mode) srclk.mode(new RPiPinMode.output_mode) end # write 'state' on register 'reg' fun write(reg: Int, state: Bool) do registers[reg] = state write_registers end # write all registers fun write_all(regs: Array[Bool]) do assert regs.length == nb_pins registers = regs write_registers end # clear all registers fun clear_registers do registers = new Array[Bool].filled_with(false, nb_pins) write_registers end private fun write_registers do rclk.write(false) var i = registers.length - 1 while i >= 0 do var reg = registers[i] srclk.write(false) ser.write(reg) srclk.write(true) i -= 1 end rclk.write(true) end end