-- | Programming the adafruit_itsybitsy_m4_express board with Copilot.

{-# LANGUAGE DataKinds #-}

module Copilot.Zephyr.Board.Adafruit_itsybitsy_m4_express (
	module Copilot.Zephyr
	, sw0
	, led0
	-- * Pins
	, pin0
	, pin1
	, pin2
	, pin3
	, pin4
	, pin7
	, pin9
	, pin10
	, pin11
	, pin12
	, pin13
	, sck
	, mosi
	, miso
) where

import Copilot.Zephyr
import Copilot.Zephyr.Internals
import Copilot.Zephyr.Board.Generic (sw0, led0)

-- TODO: a0, a1, a2-a5
-- TODO: pin5 is output-only, not input, intended for PWM, but may be able
-- to do digital output too. Current types do not allow output-only.
-- TODO: several other pins can be analog input
-- TODO: many pins support pwm, including led0
-- TODO: DotStar led (pin #6 and #8)

-- The GPIO addresses were found by reading the schematic at
-- https://learn.adafruit.com/introducing-adafruit-itsybitsy-m4/downloads
-- eg, pin0 is labeled as "D0" and connects to "PA16".

pin0, pin1, pin2, pin3, pin4, pin7, pin9, pin10 :: Pin '[ 'DigitalIO ]
pin11, pin12, pin13, sck, mosi, miso :: Pin '[ 'DigitalIO ]

-- | RX
pin0 :: Pin '[ 'DigitalIO]
pin0 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_0") (Int -> GPIOAddress
porta Int
16)) 
-- | TX
pin1 :: Pin '[ 'DigitalIO]
pin1 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_1") (Int -> GPIOAddress
porta Int
17)) 
pin2 :: Pin '[ 'DigitalIO]
pin2 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_2") (Int -> GPIOAddress
porta Int
7))
pin3 :: Pin '[ 'DigitalIO]
pin3 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_3") (Int -> GPIOAddress
portb Int
22))
pin4 :: Pin '[ 'DigitalIO]
pin4 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_4") (Int -> GPIOAddress
porta Int
15))
pin7 :: Pin '[ 'DigitalIO]
pin7 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_7") (Int -> GPIOAddress
porta Int
18))
pin9 :: Pin '[ 'DigitalIO]
pin9 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_9") (Int -> GPIOAddress
porta Int
19))
pin10 :: Pin '[ 'DigitalIO]
pin10 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_10") (Int -> GPIOAddress
porta Int
20))
pin11 :: Pin '[ 'DigitalIO]
pin11 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_11") (Int -> GPIOAddress
porta Int
21))
pin12 :: Pin '[ 'DigitalIO]
pin12 = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_12") (Int -> GPIOAddress
porta Int
23))
-- | same as led0
pin13 :: Pin '[ 'DigitalIO]
pin13 = Pin '[ 'DigitalIO]
led0 
-- | SPI SCK
sck :: Pin '[ 'DigitalIO]
sck = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_sck") (Int -> GPIOAddress
porta Int
1))
-- | SPI MOSI
mosi :: Pin '[ 'DigitalIO]
mosi = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_mosi") (Int -> GPIOAddress
porta Int
0))
-- | SPI MISO
miso :: Pin '[ 'DigitalIO]
miso = forall {k} (t :: k). Zephyr -> Pin t
Pin (GPIOAlias -> GPIOAddress -> Zephyr
Zephyr (String -> GPIOAlias
GPIOAlias String
"gpio_pin_miso") (Int -> GPIOAddress
portb Int
23))

porta :: Int -> GPIOAddress
porta :: Int -> GPIOAddress
porta Int
n = String -> GPIOAddress
GPIOAddress (String
"porta " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
n)

portb :: Int -> GPIOAddress
portb :: Int -> GPIOAddress
portb Int
n = String -> GPIOAddress
GPIOAddress (String
"portb " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
n)