1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2013 Alexis Laferrière <alexis.laf@xymus.net>
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
17 # This programs interprets the input of a physical interface thought the
18 # GPIO pins of a Raspberry Pi to control an MPD server.
20 # It suppot two inputs: a play/pause button and a rotary encoder to adjust
23 # The each data output of the volume control are connected to the board
25 module physical_interface_for_mpd_on_rpi
31 fun mpd
: MPDConnection do return once
new MPDConnection("localhost", 6600, "password")
40 fun update
: nullable Char
46 if new_a
!= old_a
or new_b
!= old_b
then
47 if not old_a
and not old_b
then
49 if not new_a
and new_b
then
51 else if new_a
and not new_b
then
54 else if old_a
and old_b
then
56 if not new_a
and new_b
then
58 else if new_a
and not new_b
then
79 var ds
= new Array[RPiPin]# = [d4,d5,d6,d7]
82 fun flag_clear_display
: Int do return 1
83 fun flag_return_home
: Int do return 2
84 fun flag_entry_mode_set
: Int do return 4
85 fun flag_display_control
: Int do return 8
86 fun flag_cursor_shift
: Int do return 16
87 fun flag_function_set
: Int do return 32
88 fun flag_set_cgram_addr
: Int do return 64
89 fun flag_set_ggram_addr
: Int do return 128
92 fun flag_entry_right
: Int do return 0
93 fun flag_entry_left
: Int do return 2
94 fun flag_entry_shift_increment
: Int do return 1
95 fun flag_entry_shift_decrement
: Int do return 0
98 fun flag_display_on
: Int do return 4
99 fun flag_display_off
: Int do return 0
100 fun flag_cursor_on
: Int do return 2
101 fun flag_cursor_off
: Int do return 0
102 fun flag_blink_on
: Int do return 1
103 fun flag_blink_off
: Int do return 0
105 # display/cursor shift
106 fun flag_display_move
: Int do return 8
107 fun flag_cursor_move
: Int do return 0
108 fun flag_move_right
: Int do return 4
109 fun flag_move_left
: Int do return 0
112 fun flag_8bit_mode
: Int do return 16
113 fun flag_4bit_mode
: Int do return 0
114 fun flag_2_lines
: Int do return 8
115 fun flag_1_line
: Int do return 0
116 fun flag_5x10_dots
: Int do return 4
117 fun flag_5x8_dots
: Int do return 0
119 fun function_set
(bits
, lines
, dots_wide
: Int)
121 var fs
= flag_function_set
124 else if bits
!= 4 then abort
128 else if lines
!= 1 then abort
130 if dots_wide
== 10 then
132 else if dots_wide
!= 8 then abort
137 fun display_control
(on
, cursor
, blink
: Bool)
139 var fs
= flag_display_control
142 fs
= fs
.bin_or
(flag_display_on
)
143 else fs
= fs
.bin_or
(flag_display_off
)
146 fs
= fs
.bin_or
(flag_cursor_on
)
147 else fs
= fs
.bin_or
(flag_cursor_off
)
150 fs
= fs
.bin_or
(flag_blink_on
)
151 else fs
= fs
.bin_or
(flag_blink_off
)
156 fun entry_mode
(left
, incr
: Bool)
158 var fs
= flag_entry_mode_set
161 fs
= fs
.bin_or
(flag_entry_left
)
162 else fs
= fs
.bin_or
(flag_entry_right
)
165 fs
= fs
.bin_or
(flag_entry_shift_increment
)
166 else fs
= fs
.bin_or
(flag_entry_shift_decrement
)
175 rs
.fsel
= new FunctionSelect.outp
176 en
.fsel
= new FunctionSelect.outp
177 d4
.fsel
= new FunctionSelect.outp
178 d5
.fsel
= new FunctionSelect.outp
179 d6
.fsel
= new FunctionSelect.outp
180 d7
.fsel
= new FunctionSelect.outp
185 # wait 20ms for power up
188 #write_4bits(true,true,false,false)
193 #write_4bits(true,true,false,false)
198 #write_4bits(true,true,false,false)
201 #200.bcm2835_delay_micros
203 #write_4bits(false,true,false,false)
212 #function_set(4, 2, 8)
216 #display_control(true, true, true)
222 # set cursor move direction
230 #entry_mode(true, true)
232 write
(true, "33".to_hex
)
233 write
(true, "32".to_hex
)
234 write
(true, "28".to_hex
)
235 write
(true, "0C".to_hex
)
236 write
(true, "01".to_hex
)
239 fun write_4_bits
(v
: Int)
241 var lb
= once
[1,2,4,8]
244 var r
= b
.bin_and
(v
) != 0
251 fun write_4bits
(a
,b
,c
,d
:Bool)
263 1.bcm2835_delay_micros
265 100.bcm2835_delay_micros
269 fun write
(is_cmd
: Bool, cmd
: Int)
275 var hb
= once
[16,32,64,128]
278 var r
= b
.bin_and
(cmd
) != 0
286 1.bcm2835_delay_micros
295 200.bcm2835_delay_micros
299 var lb
= once
[1,2,4,8]
302 var r
= b
.bin_and
(cmd
) != 0
310 1.bcm2835_delay_micros
319 200.bcm2835_delay_micros
339 for c
in v
do write
(false, c
.ascii
)
346 var status
= mpd
.status
348 if status
!= null then
349 playing
= status
.state
== "play"
354 print
"playing -> stop"
357 print
"stopped -> play"
362 assert bcm2835_init
else print
"Failed to init"
365 var out
= new RPiPin.p1_11
366 out
.fsel
= new FunctionSelect.outp
370 var inp
= new RPiPin.p1_13
371 inp
.fsel
= new FunctionSelect.inpt
372 inp
.pud
= new PUDControl.down
375 var vol3
= new RPiPin.p1_03
376 vol3
.fsel
= new FunctionSelect.inpt
377 vol3
.pud
= new PUDControl.up
380 var vol5
= new RPiPin.p1_05
381 vol5
.fsel
= new FunctionSelect.inpt
382 vol5
.pud
= new PUDControl.up
384 var vol
= new RotaryEncoder(vol3
,vol5
)
388 var lcd_rs
= new RPiPin.p1_23
389 var lcd_en
= new RPiPin.p1_21
390 var lcd_d4
= new RPiPin.p1_19
391 var lcd_d5
= new RPiPin.p1_26
392 var lcd_d6
= new RPiPin.p1_24
393 var lcd_d7
= new RPiPin.p1_22
394 var lcd
= new LCD(lcd_rs
, lcd_en
, lcd_d4
, lcd_d5
, lcd_d6
, lcd_d7
)
396 #lcd.write(false, 'a'.to_i.to_ascii)
398 lcd
.write
(false, 'a'.ascii
)
399 lcd
.write
(false, 'C'.ascii
)
407 if lev
!= last_in
then
420 mpd
.relative_volume
= -vol_step
423 mpd
.relative_volume
= vol_step
427 if tick
% 100 == 0 then
429 #var now_playing = mpd.status("")
430 #lcd.text = tick.to_s