1 /**
2  * Driver implementation
3  *
4  * Authors: Tristan Brice Velloza Kildaire
5  */
6 module bcm2835.driver;
7 
8 version(DBG_PRINT)
9 {
10 	import gogga.mixins;
11 }
12 
13 // WiringPi definitions
14 import bcm2835.wiringPi : pinMode;
15 import bcm2835.wiringPi : digitalWrite;
16 
17 // types
18 import bcm2835.types;
19 
20 
21 /** 
22  * Driver exceptions
23  */
24 public final class BCM2835Exception : Exception
25 {
26 	this(string msg)
27 	{
28 		super(msg);
29 	}
30 }
31 
32 /** 
33  * The driver itself
34  */
35 public class BCM2835 // TODO: Move to a struct type
36 {
37 	private alias dexcp = BCM2835Exception;
38 	import niknaks.meta : isVariadicArgsOf;
39 
40 	private Addressing _a;
41 	
42 	/** 
43 	 * Constructs a new driver
44 	 * instance using Broadcom
45 	 * addressing
46 	 */
47 	this()
48 	{
49 		this(Addressing.BCM);
50 	}
51 
52 	/** 
53 	 * Constructs a new driver instance
54 	 * with the given addressing mode.
55 	 *
56 	 * See_Also: `Addressing` for information
57 	 * Params:
58 	 *   aType = the addressing mode
59 	 */
60 	this(Addressing aType)
61 	{
62 		this._a = aType;
63 		setup(this._a);
64 	}
65 
66 	// TODO: Neaten up
67 	private void setup(Addressing aType)
68 	{
69 		int _s;
70 		version(WPI_NEW_SETUP)
71 		{
72 			version(DBG_PRINT) { DEBUG("About to call wiringPiSetupGpioDevice()..."); }
73 
74 			// fixme: try get wpi3 working, or document which version
75 			// works and which doesn't -0 link time error with my RPi's
76 			// current object file
77 			import bcm2835.wiringPi : wiringPiSetupGpioDevice;
78 			import bcm2835.wiringPi : WPIPinType;
79 			_s = wiringPiSetupGpioDevice(cast(WPIPinType)aType);
80 			version(DBG_PRINT) { DEBUG("wiringPiSetupGpioDevice(): ", _s); }
81 		}
82 		else
83 		{
84 			import bcm2835.wiringPi : wiringPiSetupGpio, wiringPiSetupPhys, wiringPiSetup;
85 
86 			if(aType == Addressing.WPI)
87 			{
88 				version(DBG_PRINT) { DEBUG("About to call wiringPiSetup()..."); }
89 				_s = wiringPiSetup();
90 			}
91 			else if(aType == Addressing.BCM)
92 			{
93 				version(DBG_PRINT) { DEBUG("About to call wiringPiSetupGpio()..."); }
94 				_s = wiringPiSetupGpio();
95 			}
96 			else if(aType == Addressing.PHYS)
97 			{
98 				version(DBG_PRINT) { DEBUG("About to call wiringPiSetupPhys()..."); }
99 				_s = wiringPiSetupPhys();
100 			}
101 		}
102 
103 		version(DBG_PRINT) { DEBUG("Setup function return value: ", _s); }
104 
105 		if(_s)
106 		{
107 			version(DBG_PRINT) { ERROR("Setup function returned with a non-zero value"); }
108 			throw new dexcp("Setup function returned non 1 value");
109 		}
110 	}
111 
112 	/** 
113 	 * Sets the mode of the
114 	 * given pin
115 	 *
116 	 * Params:
117 	 *   p = the pin
118 	 *   m = the mode
119 	 */
120 	public void setType(Pin p, Mode m)
121 	{
122 		version(DBG_PRINT) { DEBUG("Setting ", p, " to mode ", m); }
123 		pinMode(p, m);
124 	}
125 
126 	/** 
127 	 * Sets the given pins to
128 	 * the given mode
129 	 *
130 	 * Params:
131 	 *   pins = the pins
132 	 *   m = the mode
133 	 */
134 	public void setType(T...)(T pins, Mode m)
135 	if(isVariadicArgsOf!(Pin, T))
136 	{
137 		// generate calls based on variadic arguments
138 		static foreach(p; pins)
139 		{
140 			setType(p, m);
141 		}
142 	}
143 
144 	/** 
145 	 * Sets the given pins to
146 	 * output mode
147 	 *
148 	 * Params:
149 	 *   pins = the pins
150 	 */
151 	public void output(T...)(T pins)
152 	{
153 		setType(pins, Mode.Output);
154 	}
155 
156 	/** 
157 	 * Sets the given pins
158 	 * to input mode
159 	 *
160 	 * Params:
161 	 *   pins = the pins
162 	 */
163 	public void input(T...)(T pins)
164 	{
165 		setType(pins, Mode.Input);
166 	}
167 
168 	/** 
169 	 * Sets the given pin to the
170 	 * given state
171 	 *
172 	 * Params:
173 	 *   p = the pin
174 	 *   s = the state
175 	 */
176 	public void setState(Pin p, State s)
177 	{
178 		version(DBG_PRINT) { DEBUG("Setting ", p, " to state ", s); }
179 		digitalWrite(p, s);
180 	}
181 
182 	/** 
183 	 * Sets the given pins to the
184 	 * given state
185 	 *
186 	 * Params:
187 	 *   pins = the pins
188 	 *   s = the state
189 	 */
190 	public void setState(T...)(T pins, State s)
191 	if(isVariadicArgsOf!(Pin, T))
192 	{
193 		// generate calls based on variadic arguments
194 		static foreach(p; pins)
195 		{
196 			setState(p, s);
197 		}
198 	}
199 
200 	/** 
201 	 * Sets the given pins
202 	 * to low
203 	 *
204 	 * Params:
205 	 *   pins = the pins
206 	 */
207 	public void low(T...)(T pins)
208 	{
209 		setState(pins, State.Low);
210 	}
211 
212 	/** 
213 	 * Sets the given pins
214 	 * to high
215 	 *
216 	 * Params:
217 	 *   pins = the pins
218 	 */
219 	public void high(T...)(T pins)
220 	{
221 		setState(pins, State.High);
222 	}
223 }