module Arduino.Uno
( module Arduino.DSL
, module Arduino.Library
, GPIO()
, digitalOutput
, digitalRead
, pin2
, pin3
, pin4
, pin5
, pin6
, pin7
, pin8
, pin9
, pin10
, pin11
, pin12
, pin13
, AnalogInput()
, analogRead
, a0
, a1
, a2
, a3
, a4
, a5
, uart
, timerDelta
, every
, clock
) where
import Arduino.DSL
import Arduino.Library
import Data.Bits (shiftR, (.&.), testBit)
import Prelude hiding (Word)
data GPIO = GPIO
{ name :: String
, directionRegister :: String
, portRegister :: String
, pinRegister :: String
, bitName :: String
}
data AnalogInput = AnalogInput
{ analogName :: String
, mux :: Int
}
pin2 :: GPIO
pin2 = GPIO "pin2" "DDRD" "PORTD" "PIND" "PD2"
pin3 :: GPIO
pin3 = GPIO "pin3" "DDRD" "PORTD" "PIND" "PD3"
pin4 :: GPIO
pin4 = GPIO "pin4" "DDRD" "PORTD" "PIND" "PD4"
pin5 :: GPIO
pin5 = GPIO "pin5" "DDRD" "PORTD" "PIND" "PD5"
pin6 :: GPIO
pin6 = GPIO "pin6" "DDRD" "PORTD" "PIND" "PD6"
pin7 :: GPIO
pin7 = GPIO "pin7" "DDRD" "PORTD" "PIND" "PD7"
pin8 :: GPIO
pin8 = GPIO "pin8" "DDRB" "PORTB" "PINB" "PB0"
pin9 :: GPIO
pin9 = GPIO "pin9" "DDRB" "PORTB" "PINB" "PB1"
pin10 :: GPIO
pin10 = GPIO "pin10" "DDRB" "PORTB" "PINB" "PB2"
pin11 :: GPIO
pin11 = GPIO "pin11" "DDRB" "PORTB" "PINB" "PB3"
pin12 :: GPIO
pin12 = GPIO "pin12" "DDRB" "PORTB" "PINB" "PB4"
pin13 :: GPIO
pin13 = GPIO "pin13" "DDRB" "PORTB" "PINB" "PB5"
uart :: Output Byte
uart =
let ubrr = floor ((16000000 / (16 * 9600)) 1)
ubrrlValue = ubrr .&. 0xFF
ubrrhValue = shiftR ubrr 8 .&. 0xFF
in
createOutput
"uart"
(writeByte "UBRR0H" (byteConstant ubrrhValue) $
writeByte "UBRR0L" (byteConstant ubrrlValue) $
setBit "UCSR0C" "UCSZ01" $
setBit "UCSR0C" "UCSZ00" $
setBit "UCSR0B" "RXEN0" $
setBit "UCSR0B" "TXEN0" $
end)
(\byte ->
waitBitSet "UCSR0A" "UDRE0" $
writeByte "UDR0" byte $
end)
digitalOutput :: GPIO -> Output Bit
digitalOutput gpio =
createOutput
(name gpio)
(setBit (directionRegister gpio) (bitName gpio) $
end)
(\bit ->
writeBit (portRegister gpio) (bitName gpio) bit $
end)
digitalRead :: GPIO -> Stream Bit
digitalRead gpio = createInput
(name gpio)
(clearBit (directionRegister gpio) (bitName gpio) $
setBit (portRegister gpio) (bitName gpio) $
end)
(readBit (pinRegister gpio) (bitName gpio))
a0 :: AnalogInput
a0 = AnalogInput "a0" 0
a1 :: AnalogInput
a1 = AnalogInput "a1" 1
a2 :: AnalogInput
a2 = AnalogInput "a2" 2
a3 :: AnalogInput
a3 = AnalogInput "a3" 3
a4 :: AnalogInput
a4 = AnalogInput "a4" 4
a5 :: AnalogInput
a5 = AnalogInput "a5" 5
analogRead :: AnalogInput -> Stream Word
analogRead an = createInput
(analogName an)
(setBit "ADCSRA" "ADEN" $
setBit "ADMUX" "REFS0" $
setBit "ADCSRA" "ADPS2" $
setBit "ADCSRA" "ADPS1" $
setBit "ADCSRA" "ADPS0" $
end)
((if (testBit (mux an) 3) then setBit else clearBit) "ADMUX" "MUX3" $
(if (testBit (mux an) 2) then setBit else clearBit) "ADMUX" "MUX2" $
(if (testBit (mux an) 1) then setBit else clearBit) "ADMUX" "MUX1" $
(if (testBit (mux an) 0) then setBit else clearBit) "ADMUX" "MUX0" $
setBit "ADCSRA" "ADSC" $
waitBitCleared "ADCSRA" "ADSC" $
readTwoPartWord "ADCL" "ADCH" $
end)
timerDelta :: Stream Word
timerDelta = createInput
"timer"
(setBit "TCCR1B" "CS12" $
setBit "TCCR1B" "CS10" $
end)
(readWord "TCNT1" $
writeWord "TCNT1" (wordConstant 0) $
end)
every :: Expression Word -> Stream Word
every limit = accumulatorConstLimit limit timerDelta ~> count
clock :: Stream Word
clock = every 10000