aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/appl/arduino/blocks/test_danger_shield.fs
diff options
context:
space:
mode:
Diffstat (limited to 'amforth-6.5/appl/arduino/blocks/test_danger_shield.fs')
-rw-r--r--amforth-6.5/appl/arduino/blocks/test_danger_shield.fs437
1 files changed, 437 insertions, 0 deletions
diff --git a/amforth-6.5/appl/arduino/blocks/test_danger_shield.fs b/amforth-6.5/appl/arduino/blocks/test_danger_shield.fs
new file mode 100644
index 0000000..0b6d493
--- /dev/null
+++ b/amforth-6.5/appl/arduino/blocks/test_danger_shield.fs
@@ -0,0 +1,437 @@
+\ 2011-03-06 EW
+\ test arduino duemilanove + danger shield
+
+\ hw layout
+\ arduino | atmega328p | danger shield
+\ D0 | PD0 rx |
+\ D1 | PD1 tx |
+\ D2 | PD2 int0 |
+\ D3 | PD3 int1 oc2b | bz (buzzer)
+\ D4 | PD4 t0 | sr_in (shift register DS)
+\ D5 | PD5 t1 oc0b | led1
+\ D6 | PD6 oc0a | led2
+\ D7 | PD7 | sr_latch (shift register /OE)
+\ |
+\ D8 | PB0 icp | sr_clk (shift register SH_CP)
+\ D9 | PB1 oc1a |
+\ D10 | PB2 /ss oc1b | sw1 (switch)
+\ D11 | PB3 mosi oc2a | sw2 (switch)
+\ D12 | PB4 miso | sw3 (switch)
+\ D13 | PB5 sck |
+\ |
+\ A0 | PC0 adc0 | sl3 (slider)
+\ A1 | PC1 adc1 | sl2 (slider)
+\ A2 | PC2 adc2 | sl1 (slider)
+\ A3 | PC3 adc3 | light (photo cell)
+\ A4 | PC4 adc4 scl | temp (temperature)
+\ A5 | PC5 adc5 sda | knock (buzzer 2)
+
+\ make marker
+
+marker --start--
+
+decimal
+
+PORTB 2 portpin: sw1
+PORTB 3 portpin: sw2
+PORTB 4 portpin: sw3
+
+PORTD 5 portpin: led1
+PORTD 6 portpin: led2
+
+PORTD 3 portpin: bz
+
+PORTC 2 portpin: sl1
+PORTC 1 portpin: sl2
+PORTC 0 portpin: sl3
+
+PORTC 3 portpin: photocell
+PORTC 4 portpin: thermometer
+PORTC 5 portpin: knocksensor
+
+PORTD 4 portpin: sr_in
+PORTD 7 portpin: sr_oe \ output enable
+PORTB 0 portpin: sr_cl
+
+variable 1delay 20 1delay !
+: msg_quit
+ ." press switch 1 (D10) to quit" cr
+;
+
+
+\ --- switches -----------------------------------------------
+: sw1?
+ sw1 pin_low? if
+ 20 ms \ very simple debounce
+ sw1 pin_low? if
+ -1
+ else
+ 0
+ then
+ else
+ 0
+ then
+;
+
+\ --- buzzer -------------------------------------------------
+
+\ 2 ms T_period =^= 500 Hz
+: buzz ( cycles -- )
+ 0 ?do bz low 1ms bz high 1ms loop
+;
+
+\ --- analog digital converter -------------------------------
+\ --- adc ---
+
+: or! dup c@ rot or swap c! ;
+
+\ pin>pos
+\ convert bitmask of portpin: back to value (bitposition)
+: pin>pos ( pinmask portaddr -- pos )
+ drop ( -- pinmask )
+ log2 ( -- pos_of_most_significant_bit )
+;
+
+: adc.init ( -- )
+ \ ADMUX
+ \ A_ref is NOT connected externally
+ \ ==> need to set bit REFS0 in register ADMUX
+ [ 1 5 lshift \ ADLAR
+ 1 6 lshift or \ REFS0
+ ] literal ADMUX c!
+ \ ADCSRA
+ [ 1 7 lshift \ ADEN ADC enabled
+ 1 2 lshift or \ ADPS2 prescaler = 128
+ 1 1 lshift or \ ADPS1 .
+ 1 or \ ADPS0 .
+ ] literal ADCSRA c!
+;
+: adc.init.pin ( bitmask portaddr -- )
+ over over high
+ pin_input
+;
+
+1 6 lshift constant ADSC_MSK \ ADStartConversion bitmask
+: adc.start
+ \ start conversion
+ ADSC_MSK ADCSRA or!
+;
+: adc.wait
+ \ wait for completion of conversion
+ begin
+ ADCSRA c@ ADSC_MSK and 0=
+ until
+;
+: adc.channel! ( channel -- )
+ 7 and \ clip channel to 0..7
+ ADMUX c@ 7 invert and \ read ADMUX, clear old channel
+ or \ add new channel
+ ADMUX c! \ write
+;
+: adc.get10 ( channel -- a )
+ adc.channel! adc.start adc.wait
+\ 10 bit
+ ADCL c@
+ ADCH c@ 8 lshift + 6 rshift
+;
+: adc.get ( channel -- a )
+ adc.channel! adc.start adc.wait
+\ 8 bit
+ ADCH c@
+;
+
+\ --- shift register -----------------------------------------
+
+\ --- shift register ---
+
+: bit>sr ( bit -- )
+ if sr_in high else sr_in low then
+ sr_cl high noop sr_cl low noop
+;
+
+: get.bit ( byte pos -- bit )
+ 1 swap lshift \ -- byte bitmask
+ and \ -- bit
+;
+
+\ clock one byte out, MSB first!
+: byte>sr ( byte -- )
+ 8 0 do
+ dup 7 i - \ 7 6 5 ... 0: MSB first!
+ get.bit
+ bit>sr
+ loop
+ drop
+;
+
+: >7seg
+ invert
+ byte>sr
+ sr_oe low noop sr_oe high
+;
+
+
+create HexDigits
+$3f , \ 0
+$06 , \ 1
+$5b , \ 2
+$4f , \ 3
+$66 , \ 4
+$6d , \ 5
+$7d , \ 6
+$07 , \ 7
+$7f , \ 8
+$6f , \ 9
+$77 , \ A
+$7c , \ b
+$58 , \ c
+$5e , \ d
+$79 , \ E
+$71 , \ F
+
+$80 constant dec.point
+: emit.7seg ( n -- )
+ dup 0 $F within if
+ HexDigits + i@ >7seg
+ else
+ drop
+ then
+;
+
+\ --- convert thermometer reading --------------------------
+
+: >T
+ 51 -
+ 100 256 */
+ 25 +
+;
+
+: .T
+ thermometer pin>pos adc.get dup . space >T . cr
+;
+
+
+\ --- test functions ---------------------------------------
+: test_switches
+ ." press switch 2,3 to light up led 1,2" cr
+ msg_quit
+
+ begin
+ sw2 pin_low? if led1 high else led1 low then
+ sw3 pin_low? if led2 high else led2 low then
+ sw1? until
+;
+
+: test_buzzer
+ ." press switch 2 (D11) to test buzzer" cr
+ msg_quit
+ begin
+ sw2 pin_low? if 500 buzz then
+ sw1? until
+;
+
+: test_sliders
+ ." move sliders" cr
+ msg_quit
+ begin
+ sl1 pin>pos adc.get 4 u0.r space space
+ sl2 pin>pos adc.get 4 u0.r space space
+ sl3 pin>pos adc.get 4 u0.r $0d emit
+ 1delay @ ms
+ sw1? until
+ cr
+;
+
+: test_photocell
+ ." light/shadow photocell" cr
+ msg_quit
+ begin
+ photocell pin>pos adc.get 4 u0.r $0d emit
+ 1delay @ ms
+ sw1? until
+ cr
+;
+
+: test_thermometer
+ ." warm/cool thermometer" cr
+ msg_quit
+ begin
+ thermometer pin>pos adc.get 4 u0.r $0d emit
+ 1delay @ ms
+ sw1? until
+ cr
+;
+
+
+: test_bits.7seg
+ 8 0 do
+ 1 i lshift >7seg
+ 500 ms
+ loop
+;
+: test_emit.7seg
+ $10 0 do
+ i emit.7seg
+ 500 ms
+ loop
+;
+: test_7seg
+ ." show single segments on 7seg" cr
+ test_bits.7seg
+ 1000 ms
+ ." show hex numbers on 7seg" cr
+ test_emit.7seg
+ 1000 ms
+;
+
+\ --- main: init, run --------------------------------------
+: init
+ 20 1delay !
+
+ led1 pin_output
+ led2 pin_output
+ bz pin_output
+
+ sw1 pin_input
+ sw2 pin_input
+ sw3 pin_input
+
+ adc.init
+ sl1 adc.init.pin
+ sl2 adc.init.pin
+ sl3 adc.init.pin
+ photocell adc.init.pin
+ thermometer adc.init.pin
+ knocksensor adc.init.pin
+
+ sr_in high sr_in pin_output
+ sr_oe high sr_oe pin_output
+ sr_cl low sr_cl pin_output
+ $ff >7seg
+;
+
+
+\ --- pwm: timer/counter0, led1,2 ---
+\ D5 | PD5 t1 oc0b | led1
+\ D6 | PD6 oc0a | led2
+\ timer/counter0
+\ fast pwm mode
+\ TCCR0A bits
+\ . COM0A[1,0] = 1,0 (non inverted mode)
+\ . COM0B[1,0] = 1,0 (non inverted mode)
+\ . WGM0[1,0] = 1,1 (mode3: fast pwm)
+\ TCCR0B bits
+\ . CS[2,1,0] = 0,1,1 (clk_io/64)
+
+\ TIMSK0 TIFR0 TCNT0 TCCR0B TCCR0A OCR0B OCR0A
+
+: pwm.leds.init
+ 0 TCNT0 c! \ clear counter
+ led1 high led1 pin_output
+ led2 high led2 pin_output
+ \ TCCR0A = COM0A1 | COM0B1 | WGM01 | WGM00
+ %10100011 TCCR0A c!
+ \ TCCR0B = CS1 | CS0
+ %00000011 TCCR0B c!
+;
+\ control brightness via registers
+\ OCR0A (D6)
+\ OCR0B (D5)
+
+variable pwm5
+variable pwm6
+: test_leds_pwm
+ pwm.leds.init
+ 0 pwm5 !
+ $ff pwm6 !
+ begin
+ pwm5 @ 1+ $00ff and dup pwm5 ! OCR0B c!
+ pwm6 @ 1- $00ff and dup pwm6 ! OCR0A c!
+ 10 ms
+ key? until
+
+;
+
+: test_leds_pwm_slider
+ pwm.leds.init
+ \ adc.init
+ \ sl1 adc.init.pin
+ \ sl2 adc.init.pin
+ begin
+ sl1 pin>pos adc.get OCR0B c!
+ sl2 pin>pos adc.get OCR0A c!
+ 1 ms
+ key? until
+;
+
+
+\ --- pwm: timer/counter2, buzzer ---
+\ D3 | PD3 int1 oc2b | bz
+
+\ timer/counter2
+\ clear timer on compare match, ctc mode
+\ TCCR2A bits
+\ . COM2B[1,0] = 0,1 (non inverted mode)
+\ . WGM2[1,0] = 1,0 (mode2: ctc)
+\ TCCR2B bits
+\ . CS[2,1,0] = 1,1,1 (clk_t2s/256)
+
+\ TIMSK0 TIFR0 TCNT0 TCCR0B TCCR0A OCR0B OCR0A
+
+: pwm.bz.init
+ 0 TCNT2 c! \ clear counter
+ bz high bz pin_output
+
+ \ TCCR2A = COM0B0 | WGM01
+ %00010010 TCCR2A c!
+ \ TCCR2B = CS1 | CS0
+ %00000110 TCCR0B c!
+;
+\ control frequency via register
+\ OCR2A
+
+: test_bz_pwm
+ pwm.bz.init
+ $20 OCR2A c! 200 ms
+ $30 OCR2A c! 200 ms
+ $40 OCR2A c! 200 ms
+ $0 OCR2A c!
+;
+
+
+\ --- --- ---
+
+variable state
+8 constant max_state
+
+: run
+
+ init
+ 0 state !
+
+ ." press switch 1 (D10) for next test" cr
+ begin
+
+ sw1? if
+ state @ 1+
+ dup max_state > if drop 0 then
+ dup state !
+ . cr
+ then
+
+\ state @ 0 = ( do nothing )
+
+ state @ 1 = if test_switches then
+ state @ 2 = if test_buzzer then
+ state @ 3 = if test_sliders then
+ state @ 4 = if test_photocell then
+ state @ 5 = if test_thermometer then
+ state @ 6 = if test_7seg 1 state +! then
+
+ \ wait some
+ 1delay @ 5 * ms
+
+ key? until
+;
+
+\ fin