First commit, a first version of wiringPiOcaml works, and the shift register can be used !

This commit is contained in:
Tobias Bora 2013-12-03 10:49:04 +01:00
commit 59b417485f
8 changed files with 295 additions and 0 deletions

17
Makefile Normal file
View File

@ -0,0 +1,17 @@
CC=ocamlc
OPT=-custom
MAIN=sapin_noel.ml
SOURCES=wiringPiOcaml_stub.c wiringPiOcaml.ml shiftReg.ml
PACKAGES=unix parmap
OBJECTS=$(SOURCES)
OUTPUT=$(MAIN:.ml=.bin)
all: $(OBJECTS)
$(CC) $(OPT) -cclib -lwiringPi unix.cma $(SOURCES) $(MAIN) -o $(OUTPUT)
clean:
rm -f *.cmo *.cmi *.cmx

BIN
sapin_noel.bin Executable file

Binary file not shown.

33
sapin_noel.ml Normal file
View File

@ -0,0 +1,33 @@
open WiringPiOcaml;;
open ShiftReg;;
let _ =
(* On choisit le mode d'affichage Phys *)
setupPhys ();
(* reg : pin_value = p_v, pin_shift = p_s, pin_apply = p_a *)
(* On crée le register *)
let reg = (11,13,15) in
(* On initialise *)
let leds = initRegister reg ~nb_reg:1 in
(* On boucle pour afficher les leds unes par unes *)
while true do
for k = 0 to (Array.length leds) - 1 do
leds.(k) <- true;
applyReg reg leds;
delay 100;
leds.(k) <- false
done;
for k = (Array.length leds) - 2 downto 0 do
leds.(k) <- true;
applyReg reg leds;
delay 100;
leds.(k) <- false
done;
lightLeds leds;
applyReg reg leds;
Unix.sleep 1;
clearLeds leds;
done
;;

BIN
shiftReg.bin Executable file

Binary file not shown.

40
shiftReg.ml Normal file
View File

@ -0,0 +1,40 @@
(** This module allow to communicate with a shift-register **)
(* Source :
- http://blog.idleman.fr/raspberry-pi-20-creer-un-tableau-de-bord-connect-au-net/
- http://www.onsemi.com/pub_link/Collateral/MC74HC595A-D.PDF
*)
open WiringPiOcaml
(** reg : (pin_value = p_v, pin_shift = p_s, pin_apply = p_a). It is
used to contain the needed input **)
type reg = int * int * int;;
(** The first thing to do is setupPhys (). This function put in OUTPUT
mode the outputs and return back a bool array which represent the output of registers (begining with the first LED of the first shift register) **)
let initRegister ?nb_reg:(nb_reg = 1) reg =
let (p_v, p_s, p_a) = reg in
pinMode p_v 1; (* mode output *)
pinMode p_s 1;
pinMode p_a 1;
Array.make (8*nb_reg) false (* return back an array for all pieces *)
let write pin value = digitalWrite pin (if value then 1 else 0)
(** This function apply all modifications to the register **)
let applyReg reg leds =
let (p_v, p_s, p_a) = reg in
write p_a false;
for i = (Array.length leds) - 1 downto 0 do
write p_s false;
write p_v leds.(i);
write p_s true;
done;
write p_a true
(** Don't forget to apply it with applyReg after **)
let clearLeds leds =
Array.iteri (fun i x -> (leds.(i) <- false)) leds
let lightLeds leds =
Array.iteri (fun i x -> (leds.(i) <- true)) leds

BIN
wiringPiOcaml.bin Executable file

Binary file not shown.

67
wiringPiOcaml.ml Normal file
View File

@ -0,0 +1,67 @@
(** This module is useful to communicate with the GPIO ports of a raspberry.
It uses the wiringPi library : http://wiringpi.com/ **)
(* Test function *)
external test_hello_world : unit -> unit = "caml_hello"
(* Use it at the very beginning to choose the numeroting mode *)
external setup : unit -> int = "caml_wiringPiSetup"
external setupGio : unit -> int = "caml_wiringPiSetupGpio"
external setupPhys : unit -> int = "caml_wiringPiSetupPhys"
external setupSys : unit -> int = "caml_wiringPiSetupSys"
(* ########## Write on the device ########## *)
(* This sets the mode of a pin to either INPUT (= 0), OUTPUT (= 1), PWM_OUTPUT (= 2) or GPIO_CLOCK (= 3). Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes. *)
external pinMode : int -> int -> unit = "caml_pinMode"
(* This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. *)
external pullUpDnControl : int -> int -> unit = "caml_pullUpDnControl"
(* Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output. *)
external digitalWrite : int -> int -> unit = "caml_digitalWrite"
(* 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 *)
external pwmWrite : int -> int -> unit = "caml_pwmWrite"
(* This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin. *)
external digitalRead : int -> int = "caml_digitalRead"
external digitalWriteByte : int -> unit = "caml_digitalWriteByte"
(* ########## Timing ########## *)
(* Use it to wait a few ms or µs. If you want to wait for several
secondes, use Unix.sleep. *)
external delay : int -> unit = "caml_delay" (* wait n ms *)
external delayMicroseconds : int -> unit = "caml_delayMicroseconds" (* wait n µs *)
(* This returns a number representing the number if ms/µs since your program called one of the wiringPiSetup functions. *)
external millis : unit -> int = "caml_millis"
external micros : unit -> int = "caml_micros"
(* ################# Name of pins : ################# *)
(* +----------+-Rev2-+------+--------+------+-------+ *)
(* | wiringPi | GPIO | Phys | Name | Mode | Value | *)
(* +----------+------+------+--------+------+-------+ *)
(* | 0 | 17 | 11 | GPIO 0 | IN | Low | *)
(* | 1 | 18 | 12 | GPIO 1 | IN | High | *)
(* | 2 | 27 | 13 | GPIO 2 | IN | High | *)
(* | 3 | 22 | 15 | GPIO 3 | IN | High | *)
(* | 4 | 23 | 16 | GPIO 4 | IN | Low | *)
(* | 5 | 24 | 18 | GPIO 5 | IN | Low | *)
(* | 6 | 25 | 22 | GPIO 6 | IN | High | *)
(* | 7 | 4 | 7 | GPIO 7 | IN | High | *)
(* | 8 | 2 | 3 | SDA | IN | High | *)
(* | 9 | 3 | 5 | SCL | IN | High | *)
(* | 10 | 8 | 24 | CE0 | IN | High | *)
(* | 11 | 7 | 26 | CE1 | IN | Low | *)
(* | 12 | 10 | 19 | MOSI | IN | High | *)
(* | 13 | 9 | 21 | MISO | IN | High | *)
(* | 14 | 11 | 23 | SCLK | IN | High | *)
(* | 15 | 14 | 8 | TxD | ALT0 | High | *)
(* | 16 | 15 | 10 | RxD | ALT0 | High | *)
(* | 17 | 28 | 3 | GPIO 8 | OUT | High | *)
(* | 18 | 29 | 4 | GPIO 9 | IN | Low | *)
(* | 19 | 30 | 5 | GPIO10 | IN | Low | *)
(* | 20 | 31 | 6 | GPIO11 | IN | Low | *)
(* +----------+------+------+--------+------+-------+ *)

138
wiringPiOcaml_stub.c Normal file
View File

@ -0,0 +1,138 @@
/* ********************************************
This file make the link between wiringPi
and wiringPiOcaml
******************************************** */
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <stdio.h>
#include <wiringPi.h>
#include <wiringShift.h>
CAMLprim
value caml_hello(value unit) {
CAMLparam1(unit);
printf("Hello world!\n");
CAMLreturn(Val_unit);
}
CAMLprim
value caml_wiringPiSetup(value unit)
{
CAMLparam1(unit);
CAMLreturn(Val_int(wiringPiSetup()));
}
CAMLprim
value caml_wiringPiSetupGpio(value unit)
{
CAMLparam1(unit);
CAMLreturn(Val_int(wiringPiSetupGpio()));
}
CAMLprim
value caml_wiringPiSetupPhys(value unit)
{
CAMLparam1(unit);
CAMLreturn(Val_int(wiringPiSetupPhys()));
}
CAMLprim
value caml_wiringPiSetupSys(value unit)
{
CAMLparam1(unit);
CAMLreturn(Val_int(wiringPiSetupSys()));
}
// Core functions
CAMLprim
value caml_pinMode(value pin, value mode)
{
CAMLparam2(pin, mode);
pinMode(Int_val(pin), Int_val(mode));
CAMLreturn(Val_unit);
}
CAMLprim
value caml_pullUpDnControl(value pin, value pud)
{
CAMLparam2(pin, pud);
pullUpDnControl(Int_val(pin), Int_val(pin));
CAMLreturn(Val_unit);
}
CAMLprim
value caml_digitalWrite(value pin, value value_p)
{
CAMLparam2(pin, value_p);
digitalWrite(Int_val(pin), Int_val(value_p));
CAMLreturn(Val_unit);
}
CAMLprim
value caml_pwmWrite(value pin, value value_p)
{
CAMLparam2(pin, value_p);
pwmWrite(Int_val(pin), Int_val(value_p));
CAMLreturn(Val_unit);
}
CAMLprim
value caml_digitalRead(value pin)
{
CAMLparam1(pin);
CAMLreturn(Val_int(digitalRead(Int_val(pin))));
}
// AnalogRead and AnalogWrite needs to be added (module must be added)
// Raspberry Pi Specifics
CAMLprim
value caml_digitalWriteByte(value value_p)
{
CAMLparam1(value_p);
digitalWriteByte(Int_val(value_p));
CAMLreturn(Val_unit);
}
// Others can be added...
// Shift Library
// Timing
/* This returns a number representing the number if milliseconds since your program called one of the wiringPiSetup functions. */
CAMLprim
value caml_millis(value unit)
{
CAMLparam1(unit);
CAMLreturn(Val_int(millis()));
}
/* This returns a number representing the number of microseconds since your program called one of the wiringPiSetup functions. */
CAMLprim
value caml_micros(value unit)
{
CAMLparam1(unit);
CAMLreturn(Val_int(micros()));
}
/* This causes program execution to pause for at least howLong milliseconds. Due to the multi-tasking nature of Linux it could be longer. */
CAMLprim
value caml_delay(value howLong)
{
CAMLparam1(howLong);
delay(Int_val(howLong));
CAMLreturn(Val_unit);
}
/* This causes program execution to pause for at least howLong microseconds. Due to the multi-tasking nature of Linux it could be longer. Delays under 100 microseconds are timed using a hard-coded loop continually polling the system time, Delays over 100 microseconds are done using the system nanosleep() function You may need to consider the implications of very short delays on the overall performance of the system, especially if using threads. */
CAMLprim
value caml_delayMicroseconds(value howLong)
{
CAMLparam1(howLong);
delayMicroseconds(Int_val(howLong));
CAMLreturn(Val_unit);
}